diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 4d89b5718f9..0039e117d57 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -49,18 +49,6 @@ compile-production-assets:
after_script:
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
-compile-production-assets-esbuild:
- allow_failure: true
- extends:
- - .compile-assets-base
- - .frontend:rules:compile-production-assets
- variables:
- NODE_ENV: "production"
- RAILS_ENV: "production"
- WEBPACK_USE_ESBUILD_LOADER: "true"
- after_script:
- - rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
-
compile-test-assets:
extends:
- .compile-assets-base
@@ -73,14 +61,6 @@ compile-test-assets:
- "${WEBPACK_COMPILE_LOG_PATH}"
when: always
-compile-test-assets-esbuild:
- allow_failure: true
- extends:
- - .compile-assets-base
- - .frontend:rules:compile-test-assets
- variables:
- WEBPACK_USE_ESBUILD_LOADER: "true"
-
compile-test-assets as-if-foss:
extends:
- compile-test-assets
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml
index ecbb2c967c9..99a1ff30fc3 100644
--- a/.rubocop_todo/layout/argument_alignment.yml
+++ b/.rubocop_todo/layout/argument_alignment.yml
@@ -532,17 +532,6 @@ Layout/ArgumentAlignment:
- 'app/models/ci/running_build.rb'
- 'app/models/ci/stage.rb'
- 'app/models/clusters/kubernetes_namespace.rb'
- - 'app/models/concerns/bulk_member_access_load.rb'
- - 'app/models/concerns/ci/metadatable.rb'
- - 'app/models/concerns/discussion_on_diff.rb'
- - 'app/models/concerns/group_descendant.rb'
- - 'app/models/concerns/integrations/has_issue_tracker_fields.rb'
- - 'app/models/concerns/issuable.rb'
- - 'app/models/concerns/limitable.rb'
- - 'app/models/concerns/mentionable/reference_regexes.rb'
- - 'app/models/concerns/resolvable_discussion.rb'
- - 'app/models/concerns/vulnerability_finding_helpers.rb'
- - 'app/models/concerns/web_hooks/auto_disabling.rb'
- 'app/models/container_repository.rb'
- 'app/models/cycle_analytics/project_level_stage_adapter.rb'
- 'app/models/deployment.rb'
@@ -1142,8 +1131,6 @@ Layout/ArgumentAlignment:
- 'ee/app/mailers/emails/namespace_storage_usage_mailer.rb'
- 'ee/app/models/approval_wrapped_rule.rb'
- 'ee/app/models/ci/minutes/notification.rb'
- - 'ee/app/models/concerns/ee/protected_ref_access.rb'
- - 'ee/app/models/concerns/geo/verifiable_replicator.rb'
- 'ee/app/models/dast/pre_scan_verification.rb'
- 'ee/app/models/deployments/approval.rb'
- 'ee/app/models/ee/application_setting.rb'
@@ -1523,12 +1510,6 @@ Layout/ArgumentAlignment:
- 'ee/spec/models/approval_wrapped_code_owner_rule_spec.rb'
- 'ee/spec/models/ci/bridge_spec.rb'
- 'ee/spec/models/ci/build_spec.rb'
- - 'ee/spec/models/concerns/elastic/issue_spec.rb'
- - 'ee/spec/models/concerns/elastic/merge_request_spec.rb'
- - 'ee/spec/models/concerns/elastic/note_spec.rb'
- - 'ee/spec/models/concerns/elastic/project_spec.rb'
- - 'ee/spec/models/concerns/elastic/repository_spec.rb'
- - 'ee/spec/models/concerns/elastic/snippet_spec.rb'
- 'ee/spec/models/dast/pre_scan_verification_step_spec.rb'
- 'ee/spec/models/dast_site_profile_spec.rb'
- 'ee/spec/models/deployments/approval_summary_spec.rb'
@@ -2611,13 +2592,6 @@ Layout/ArgumentAlignment:
- 'spec/models/clusters/kubernetes_namespace_spec.rb'
- 'spec/models/clusters/platforms/kubernetes_spec.rb'
- 'spec/models/commit_spec.rb'
- - 'spec/models/concerns/ci/partitionable/switch_spec.rb'
- - 'spec/models/concerns/ci/partitionable_spec.rb'
- - 'spec/models/concerns/ci/track_environment_usage_spec.rb'
- - 'spec/models/concerns/database_event_tracking_spec.rb'
- - 'spec/models/concerns/deployment_platform_spec.rb'
- - 'spec/models/concerns/issuable_spec.rb'
- - 'spec/models/concerns/token_authenticatable_spec.rb'
- 'spec/models/container_repository_spec.rb'
- 'spec/models/deployment_spec.rb'
- 'spec/models/design_management/version_spec.rb'
@@ -2995,11 +2969,6 @@ Layout/ArgumentAlignment:
- 'spec/support/shared_examples/lib/sentry/client_shared_examples.rb'
- 'spec/support/shared_examples/models/chat_integration_shared_examples.rb'
- 'spec/support/shared_examples/models/clusters/prometheus_client_shared.rb'
- - 'spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb'
- - 'spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb'
- - 'spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb'
- - 'spec/support/shared_examples/models/concerns/timebox_shared_examples.rb'
- - 'spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb'
- 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
- 'spec/support/shared_examples/models/member_shared_examples.rb'
- 'spec/support/shared_examples/observability/csp_shared_examples.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index d3a55c5d9c5..fc00a030fe1 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -2318,7 +2318,6 @@ RSpec/ContextWording:
- 'spec/models/personal_access_token_spec.rb'
- 'spec/models/plan_limits_spec.rb'
- 'spec/models/preloaders/labels_preloader_spec.rb'
- - 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/project_authorization_spec.rb'
- 'spec/models/project_feature_spec.rb'
- 'spec/models/project_feature_usage_spec.rb'
diff --git a/.rubocop_todo/rspec/described_class.yml b/.rubocop_todo/rspec/described_class.yml
index 3a505885c9a..94c44a144bf 100644
--- a/.rubocop_todo/rspec/described_class.yml
+++ b/.rubocop_todo/rspec/described_class.yml
@@ -162,7 +162,6 @@ RSpec/DescribedClass:
- 'spec/models/performance_monitoring/prometheus_panel_spec.rb'
- 'spec/models/postgresql/detached_partition_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
- - 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/project_spec.rb'
- 'spec/models/projects/topic_spec.rb'
- 'spec/models/release_highlight_spec.rb'
diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml
index 6ba95776245..b72df55e9a8 100644
--- a/.rubocop_todo/rspec/missing_feature_category.yml
+++ b/.rubocop_todo/rspec/missing_feature_category.yml
@@ -5444,7 +5444,6 @@ RSpec/MissingFeatureCategory:
- 'spec/models/preloaders/project_root_ancestor_preloader_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
- - 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/product_analytics_event_spec.rb'
- 'spec/models/programming_language_spec.rb'
- 'spec/models/project_authorization_spec.rb'
diff --git a/Gemfile b/Gemfile
index abe77b36741..f997e52a6ab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -527,7 +527,7 @@ gem 'flipper', '~> 0.25.0'
gem 'flipper-active_record', '~> 0.25.0'
gem 'flipper-active_support_cache_store', '~> 0.25.0'
gem 'unleash', '~> 3.2.2'
-gem 'gitlab-experiment', '~> 0.8.0'
+gem 'gitlab-experiment', '~> 0.7.1'
# Structured logging
gem 'lograge', '~> 0.5'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index d740ef39aeb..c93e1905182 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -206,7 +206,7 @@
{"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"},
{"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
{"name":"gitlab-dangerfiles","version":"3.8.0","platform":"ruby","checksum":"7ef0c3205faa38a2ada19ee5b8e4012ea696611aa02564a4a95eaf3fb26d1a7e"},
-{"name":"gitlab-experiment","version":"0.8.0","platform":"ruby","checksum":"b4e2f73e0af19cdd899a745f5a846c1318d44054e068a8f4ac887f6b1017d3f9"},
+{"name":"gitlab-experiment","version":"0.7.1","platform":"ruby","checksum":"166dddb3aa83428bcaa93c35684ed01dc4d61f321fd2ae40b020806dc54a7824"},
{"name":"gitlab-fog-azure-rm","version":"1.7.0","platform":"ruby","checksum":"969c67943c54ad4c259a6acd040493f13922fbdf2211bb4eca00e71505263dc2"},
{"name":"gitlab-labkit","version":"0.31.1","platform":"ruby","checksum":"3e3a39370966b5d2739c2d9d9005c0ea27541d32cb7292e856e8bd74c720bffb"},
{"name":"gitlab-license","version":"2.2.1","platform":"ruby","checksum":"39fcf6be8b2887df8afe01b5dcbae8d08b7c5d937ff56b0fb40484a8c4f02d30"},
diff --git a/Gemfile.lock b/Gemfile.lock
index d1946ec0f70..7fdb84df413 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -590,7 +590,7 @@ GEM
danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
rake
- gitlab-experiment (0.8.0)
+ gitlab-experiment (0.7.1)
activesupport (>= 3.0)
request_store (>= 1.0)
gitlab-fog-azure-rm (1.7.0)
@@ -1718,7 +1718,7 @@ DEPENDENCIES
gitaly (~> 15.9.0.pre.rc3)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.8.0)
- gitlab-experiment (~> 0.8.0)
+ gitlab-experiment (~> 0.7.1)
gitlab-fog-azure-rm (~> 1.7.0)
gitlab-labkit (~> 0.31.1)
gitlab-license (~> 2.2.1)
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 5b1a7f0bab7..6fdd4906613 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -339,7 +339,6 @@ class Projects::PipelinesController < Projects::ApplicationController
return if helpers.has_gitlab_ci?(project)
experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
- e.control {}
e.candidate {}
end
end
diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb
index 90806df1d64..823332c3d1d 100644
--- a/app/helpers/ci/pipelines_helper.rb
+++ b/app/helpers/ci/pipelines_helper.rb
@@ -105,12 +105,10 @@ module Ci
}
experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
- e.control {} # rubocop:disable Lint/EmptyBlock
e.candidate { data[:any_runners_available] = project.active_runners.exists?.to_s }
end
experiment(:ios_specific_templates, actor: current_user, project: project, sticky_to: project) do |e|
- e.control {} # rubocop:disable Lint/EmptyBlock
e.candidate do
data[:registration_token] = project.runners_token if can?(current_user, :register_project_runners, project)
data[:ios_runners_available] = (project.shared_runners_available? && Gitlab.com?).to_s
diff --git a/app/helpers/ide_helper.rb b/app/helpers/ide_helper.rb
index 2f25afb8057..063eef41f77 100644
--- a/app/helpers/ide_helper.rb
+++ b/app/helpers/ide_helper.rb
@@ -72,7 +72,6 @@ module IdeHelper
def enable_environments_guidance?(project)
experiment(:in_product_guidance_environments_webide, project: project) do |e|
- e.control { 'false' }
e.candidate { !has_dismissed_ide_environments_callout? }
e.run
diff --git a/app/models/concerns/bulk_member_access_load.rb b/app/models/concerns/bulk_member_access_load.rb
index c3aa3019abb..11e88ee3372 100644
--- a/app/models/concerns/bulk_member_access_load.rb
+++ b/app/models/concerns/bulk_member_access_load.rb
@@ -5,16 +5,20 @@ module BulkMemberAccessLoad
included do
def merge_value_to_request_store(resource_klass, resource_id, value)
- Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(resource_klass),
- resource_ids: [resource_id],
- default_value: Gitlab::Access::NO_ACCESS) do
+ Gitlab::SafeRequestLoader.execute(
+ resource_key: max_member_access_for_resource_key(resource_klass),
+ resource_ids: [resource_id],
+ default_value: Gitlab::Access::NO_ACCESS
+ ) do
{ resource_id => value }
end
end
def purge_resource_id_from_request_store(resource_klass, resource_id)
- Gitlab::SafeRequestPurger.execute(resource_key: max_member_access_for_resource_key(resource_klass),
- resource_ids: [resource_id])
+ Gitlab::SafeRequestPurger.execute(
+ resource_key: max_member_access_for_resource_key(resource_klass),
+ resource_ids: [resource_id]
+ )
end
def max_member_access_for_resource_key(klass)
diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb
index d91f33452a0..1c6b82d6ea7 100644
--- a/app/models/concerns/ci/metadatable.rb
+++ b/app/models/concerns/ci/metadatable.rb
@@ -9,10 +9,11 @@ module Ci
extend ActiveSupport::Concern
included do
- has_one :metadata, class_name: 'Ci::BuildMetadata',
- foreign_key: :build_id,
- inverse_of: :build,
- autosave: true
+ has_one :metadata,
+ class_name: 'Ci::BuildMetadata',
+ foreign_key: :build_id,
+ inverse_of: :build,
+ autosave: true
accepts_nested_attributes_for :metadata
diff --git a/app/models/concerns/discussion_on_diff.rb b/app/models/concerns/discussion_on_diff.rb
index 40891073738..d3ebda2702d 100644
--- a/app/models/concerns/discussion_on_diff.rb
+++ b/app/models/concerns/discussion_on_diff.rb
@@ -7,20 +7,20 @@ module DiscussionOnDiff
NUMBER_OF_TRUNCATED_DIFF_LINES = 16
included do
- delegate :line_code,
- :original_line_code,
- :note_diff_file,
- :diff_line,
- :active?,
- :created_at_diff?,
- to: :first_note
+ delegate :line_code,
+ :original_line_code,
+ :note_diff_file,
+ :diff_line,
+ :active?,
+ :created_at_diff?,
+ to: :first_note
- delegate :file_path,
- :blob,
- :highlighted_diff_lines,
- :diff_lines,
- to: :diff_file,
- allow_nil: true
+ delegate :file_path,
+ :blob,
+ :highlighted_diff_lines,
+ :diff_lines,
+ to: :diff_file,
+ allow_nil: true
end
def diff_discussion?
diff --git a/app/models/concerns/group_descendant.rb b/app/models/concerns/group_descendant.rb
index 224ac8930b5..de316446e14 100644
--- a/app/models/concerns/group_descendant.rb
+++ b/app/models/concerns/group_descendant.rb
@@ -60,10 +60,7 @@ module GroupDescendant
end
if parent && parent != hierarchy_top
- expand_hierarchy_for_child(parent,
- { parent => hierarchy },
- hierarchy_top,
- preloaded)
+ expand_hierarchy_for_child(parent, { parent => hierarchy }, hierarchy_top, preloaded)
else
hierarchy
end
diff --git a/app/models/concerns/integrations/has_issue_tracker_fields.rb b/app/models/concerns/integrations/has_issue_tracker_fields.rb
index 57f8e21c5a6..223191fb963 100644
--- a/app/models/concerns/integrations/has_issue_tracker_fields.rb
+++ b/app/models/concerns/integrations/has_issue_tracker_fields.rb
@@ -8,29 +8,29 @@ module Integrations
self.field_storage = :data_fields
field :project_url,
- required: true,
- title: -> { _('Project URL') },
- help: -> do
- s_('IssueTracker|The URL to the project in the external issue tracker.')
- end
+ required: true,
+ title: -> { _('Project URL') },
+ help: -> do
+ s_('IssueTracker|The URL to the project in the external issue tracker.')
+ end
field :issues_url,
- required: true,
- title: -> { s_('IssueTracker|Issue URL') },
- help: -> do
- ERB::Util.html_escape(
- s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.')
- ) % {
- colon_id: ':id'.html_safe
- }
- end
+ required: true,
+ title: -> { s_('IssueTracker|Issue URL') },
+ help: -> do
+ ERB::Util.html_escape(
+ s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.')
+ ) % {
+ colon_id: ':id'.html_safe
+ }
+ end
field :new_issue_url,
- required: true,
- title: -> { s_('IssueTracker|New issue URL') },
- help: -> do
- s_('IssueTracker|The URL to create an issue in the external issue tracker.')
- end
+ required: true,
+ title: -> { s_('IssueTracker|New issue URL') },
+ help: -> do
+ s_('IssueTracker|The URL to create an issue in the external issue tracker.')
+ end
end
end
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index c1c1691e424..6594884ca0a 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -84,11 +84,11 @@ module Issuable
has_one :metrics, inverse_of: model_name.singular.to_sym, autosave: true
delegate :name,
- :email,
- :public_email,
- to: :author,
- allow_nil: true,
- prefix: true
+ :email,
+ :public_email,
+ to: :author,
+ allow_nil: true,
+ prefix: true
validates :author, presence: true
validates :title, presence: true, length: { maximum: TITLE_LENGTH_MAX }
@@ -345,8 +345,7 @@ module Issuable
order_milestone_due_asc
.order_labels_priority(excluded_labels: excluded_labels, extra_select_columns: [milestones_due_date])
- .reorder(milestones_due_date_with_direction.nulls_last,
- highest_priority_arel_with_direction.nulls_last)
+ .reorder(milestones_due_date_with_direction.nulls_last, highest_priority_arel_with_direction.nulls_last)
end
def order_labels_priority(direction = 'ASC', excluded_labels: [], extra_select_columns: [], with_cte: false)
@@ -620,8 +619,10 @@ module Issuable
end
def updated_tasks
- Taskable.get_updated_tasks(old_content: previous_changes['description'].first,
- new_content: description)
+ Taskable.get_updated_tasks(
+ old_content: previous_changes['description'].first,
+ new_content: description
+ )
end
##
diff --git a/app/models/concerns/limitable.rb b/app/models/concerns/limitable.rb
index 0cccb7b51a8..7ed7f65ca57 100644
--- a/app/models/concerns/limitable.rb
+++ b/app/models/concerns/limitable.rb
@@ -59,7 +59,10 @@ module Limitable
def check_plan_limit_not_exceeded(limits, relation)
return unless limits&.exceeded?(limit_name, relation)
- errors.add(:base, _("Maximum number of %{name} (%{count}) exceeded") %
- { name: limit_name.humanize(capitalize: false), count: limits.public_send(limit_name) }) # rubocop:disable GitlabSecurity/PublicSend
+ errors.add(
+ :base,
+ _("Maximum number of %{name} (%{count}) exceeded") %
+ { name: limit_name.humanize(capitalize: false), count: limits.public_send(limit_name) } # rubocop:disable GitlabSecurity/PublicSend
+ )
end
end
diff --git a/app/models/concerns/mentionable/reference_regexes.rb b/app/models/concerns/mentionable/reference_regexes.rb
index e68574c5fca..0265d609e19 100644
--- a/app/models/concerns/mentionable/reference_regexes.rb
+++ b/app/models/concerns/mentionable/reference_regexes.rb
@@ -5,9 +5,7 @@ module Mentionable
extend Gitlab::Utils::StrongMemoize
def self.reference_pattern(link_patterns, issue_pattern)
- Regexp.union(link_patterns,
- issue_pattern,
- *other_patterns)
+ Regexp.union(link_patterns, issue_pattern, *other_patterns)
end
def self.other_patterns
diff --git a/app/models/concerns/resolvable_discussion.rb b/app/models/concerns/resolvable_discussion.rb
index 141c480ea1f..45818942326 100644
--- a/app/models/concerns/resolvable_discussion.rb
+++ b/app/models/concerns/resolvable_discussion.rb
@@ -24,14 +24,14 @@ module ResolvableDiscussion
)
delegate :potentially_resolvable?,
- :noteable_id,
- :noteable_type,
- to: :first_note
+ :noteable_id,
+ :noteable_type,
+ to: :first_note
- delegate :resolved_at,
- :resolved_by,
- to: :last_resolved_note,
- allow_nil: true
+ delegate :resolved_at,
+ :resolved_by,
+ to: :last_resolved_note,
+ allow_nil: true
end
def resolved_by_push?
diff --git a/app/models/concerns/vulnerability_finding_helpers.rb b/app/models/concerns/vulnerability_finding_helpers.rb
index 1e8a290c050..a5b69997900 100644
--- a/app/models/concerns/vulnerability_finding_helpers.rb
+++ b/app/models/concerns/vulnerability_finding_helpers.rb
@@ -47,8 +47,9 @@ module VulnerabilityFindingHelpers
report_finding = report_finding_for(security_finding)
return Vulnerabilities::Finding.new unless report_finding
- finding_data = report_finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :links, :signatures,
- :flags, :evidence)
+ finding_data = report_finding.to_hash.except(
+ :compare_key, :identifiers, :location, :scanner, :links, :signatures, :flags, :evidence
+ )
identifiers = report_finding.identifiers.uniq(&:fingerprint).map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash.merge({ project: project }))
end
diff --git a/app/models/concerns/web_hooks/auto_disabling.rb b/app/models/concerns/web_hooks/auto_disabling.rb
index 05aaca32f35..2ad2e47ec4e 100644
--- a/app/models/concerns/web_hooks/auto_disabling.rb
+++ b/app/models/concerns/web_hooks/auto_disabling.rb
@@ -39,8 +39,11 @@ module WebHooks
scope :disabled, -> do
return none unless auto_disabling_enabled?
- where('recent_failures > ? AND (disabled_until IS NULL OR disabled_until >= ?)',
- FAILURE_THRESHOLD, Time.current)
+ where(
+ 'recent_failures > ? AND (disabled_until IS NULL OR disabled_until >= ?)',
+ FAILURE_THRESHOLD,
+ Time.current
+ )
end
# A hook is executable if:
@@ -52,8 +55,12 @@ module WebHooks
scope :executable, -> do
return all unless auto_disabling_enabled?
- where('recent_failures <= ? OR (recent_failures > ? AND (disabled_until IS NOT NULL) AND (disabled_until < ?))',
- FAILURE_THRESHOLD, FAILURE_THRESHOLD, Time.current)
+ where(
+ 'recent_failures <= ? OR (recent_failures > ? AND (disabled_until IS NOT NULL) AND (disabled_until < ?))',
+ FAILURE_THRESHOLD,
+ FAILURE_THRESHOLD,
+ Time.current
+ )
end
end
diff --git a/app/models/preloaders/users_max_access_level_by_project_preloader.rb b/app/models/preloaders/users_max_access_level_by_project_preloader.rb
new file mode 100644
index 00000000000..37842665e7d
--- /dev/null
+++ b/app/models/preloaders/users_max_access_level_by_project_preloader.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Preloaders
+ # This class preloads the max access level (role) for the users within the given projects and
+ # stores the values in requests store via the ProjectTeam class.
+ class UsersMaxAccessLevelByProjectPreloader
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(project_users:)
+ @project_users = project_users.transform_values { |users| Array.wrap(users) }
+ end
+
+ def execute
+ return unless @project_users.present?
+
+ all_users = @project_users.values.flatten.uniq
+ preload_users_namespace_bans(all_users)
+
+ @project_users.each do |project, users|
+ users.each do |user|
+ access_level = access_levels.fetch([project.id, user.id], Gitlab::Access::NO_ACCESS)
+ project.team.write_member_access_for_user_id(user.id, access_level)
+ end
+ end
+ end
+
+ private
+
+ def access_levels
+ query = ProjectAuthorization.none
+
+ @project_users.each do |project, users|
+ query = query.or(
+ ProjectAuthorization
+ .where(project_id: project.id, user_id: users.map(&:id))
+ )
+ end
+
+ query
+ .group(:project_id, :user_id)
+ .maximum(:access_level)
+ end
+ strong_memoize_attr :access_levels
+
+ def preload_users_namespace_bans(_users)
+ # overridden in EE
+ end
+ end
+end
+
+Preloaders::UsersMaxAccessLevelByProjectPreloader.prepend_mod
diff --git a/app/models/preloaders/users_max_access_level_in_projects_preloader.rb b/app/models/preloaders/users_max_access_level_in_projects_preloader.rb
deleted file mode 100644
index f32184f168d..00000000000
--- a/app/models/preloaders/users_max_access_level_in_projects_preloader.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-module Preloaders
- # This class preloads the max access level (role) for the users within the given projects and
- # stores the values in requests store via the ProjectTeam class.
- class UsersMaxAccessLevelInProjectsPreloader
- def initialize(projects:, users:)
- @projects = projects
- @users = users
- end
-
- def execute
- return unless @projects.present? && @users.present?
-
- preload_users_namespace_bans(@users)
-
- access_levels.each do |(project_id, user_id), access_level|
- project = projects_by_id[project_id]
-
- project.team.write_member_access_for_user_id(user_id, access_level)
- end
- end
-
- private
-
- def access_levels
- ProjectAuthorization
- .where(project_id: project_ids, user_id: user_ids)
- .group(:project_id, :user_id)
- .maximum(:access_level)
- end
-
- # Use reselect to override the existing select to prevent
- # the error `subquery has too many columns`
- # NotificationsController passes in an Array so we need to check the type
- def project_ids
- @projects.is_a?(ActiveRecord::Relation) ? @projects.reselect(:id) : @projects
- end
-
- def user_ids
- @users.is_a?(ActiveRecord::Relation) ? @users.reselect(:id) : @users
- end
-
- def projects_by_id
- @projects_by_id ||= @projects.index_by(&:id)
- end
-
- def preload_users_namespace_bans(_users)
- # overridden in EE
- end
- end
-end
-
-Preloaders::UsersMaxAccessLevelInProjectsPreloader.prepend_mod
diff --git a/app/models/work_item.rb b/app/models/work_item.rb
index a7cd522f023..a70f0957fa9 100644
--- a/app/models/work_item.rb
+++ b/app/models/work_item.rb
@@ -130,6 +130,75 @@ class WorkItem < Issue
::Gitlab::WorkItems::WorkItemHierarchy.new(base, options: options)
end
+
+ override :allowed_work_item_type_change
+ def allowed_work_item_type_change
+ return unless work_item_type_id_changed?
+
+ child_links = WorkItems::ParentLink.for_parents(id)
+ parent_link = ::WorkItems::ParentLink.find_by(work_item: self)
+
+ validate_parent_restrictions(parent_link)
+ validate_child_restrictions(child_links)
+ validate_depth(parent_link, child_links)
+ end
+
+ def validate_parent_restrictions(parent_link)
+ return unless parent_link
+
+ parent_link.work_item.work_item_type_id = work_item_type_id
+
+ unless parent_link.valid?
+ errors.add(
+ :work_item_type_id,
+ format(
+ _('cannot be changed to %{new_type} with %{parent_type} as parent type.'),
+ new_type: work_item_type.name, parent_type: parent_link.work_item_parent.work_item_type.name
+ )
+ )
+ end
+ end
+
+ def validate_child_restrictions(child_links)
+ return if child_links.empty?
+
+ child_type_ids = child_links.joins(:work_item).select(self.class.arel_table[:work_item_type_id]).distinct
+ restrictions = ::WorkItems::HierarchyRestriction.where(
+ parent_type_id: work_item_type_id,
+ child_type_id: child_type_ids
+ )
+
+ # We expect a restriction for every child type
+ if restrictions.size < child_type_ids.size
+ errors.add(
+ :work_item_type_id,
+ format(_('cannot be changed to %{new_type} with these child item types.'), new_type: work_item_type.name)
+ )
+ end
+ end
+
+ def validate_depth(parent_link, child_links)
+ restriction = ::WorkItems::HierarchyRestriction.find_by_parent_type_id_and_child_type_id(
+ work_item_type_id,
+ work_item_type_id
+ )
+ return unless restriction&.maximum_depth
+
+ children_with_new_type = self.class.where(id: child_links.select(:work_item_id))
+ .where(work_item_type_id: work_item_type_id)
+ max_child_depth = ::Gitlab::WorkItems::WorkItemHierarchy.new(children_with_new_type).max_descendants_depth.to_i
+
+ ancestor_depth =
+ if parent_link&.work_item_parent && parent_link.work_item_parent.work_item_type_id == work_item_type_id
+ parent_link.work_item_parent.same_type_base_and_ancestors.count
+ else
+ 0
+ end
+
+ if max_child_depth + ancestor_depth > restriction.maximum_depth - 1
+ errors.add(:work_item_type_id, _('reached maximum depth'))
+ end
+ end
end
WorkItem.prepend_mod
diff --git a/config/esbuild.config.js b/config/esbuild.config.js
deleted file mode 100644
index b17548d8300..00000000000
--- a/config/esbuild.config.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const browserslist = require('browserslist');
-const esbuild = require('esbuild');
-
-const ESBUILD_SUPPORTED_TARGETS = new Set([
- 'chrome',
- 'edge',
- 'firefox',
- 'hermes',
- 'ie',
- 'ios',
- 'node',
- 'opera',
- 'rhino',
- 'safari',
-]);
-
-const parseBrowserslist = (browserslistResult) => {
- return browserslistResult.map((browsers) => {
- const [family, version] = browsers.split(' ');
- let normalizedVersion = version;
-
- // browserslist can return a range: safari15.2-15.4
- if (version.indexOf('-') >= -1) {
- // we take the lowest version
- [normalizedVersion] = version.split('-');
- }
-
- return {
- family,
- version: normalizedVersion,
- };
- });
-};
-
-const mapBrowserslistToESBuildTarget = (browsersList) => {
- return parseBrowserslist(browsersList)
- .filter(({ family, version }) => {
- if (!ESBUILD_SUPPORTED_TARGETS.has(family)) {
- console.warning('Unknown ESBuild target %s, version %s', family, version);
- return false;
- }
-
- return true;
- })
- .map(({ family, version }) => {
- return `${family}${version}`;
- });
-};
-
-module.exports = {
- target: mapBrowserslistToESBuildTarget(browserslist()),
- supported: {
- 'optional-chain': false,
- 'nullish-coalescing': false,
- 'class-static-field': false,
- 'class-field': false,
- },
- implementation: esbuild,
- /**
- * It's necessary to tell esbuild to use the 'js' loader
- * because esbuild cannot auto-detect which loader to use
- * based on the .vue extension.
- */
- loader: 'js',
-};
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 3308fa3d210..0859248ad49 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -31,14 +31,11 @@ const { VueLoaderPlugin } = require(VUE_LOADER_MODULE);
const VUE_LOADER_VERSION = require(`${VUE_LOADER_MODULE}/package.json`).version;
const VUE_VERSION = require('vue/package.json').version;
-const { EsbuildPlugin } = require('esbuild-loader');
-
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { StatsWriterPlugin } = require('webpack-stats-plugin');
const WEBPACK_VERSION = require('webpack/package.json').version;
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
-const esbuildConfiguration = require('./esbuild.config');
const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler');
const IS_EE = require('./helpers/is_ee_env');
@@ -58,8 +55,6 @@ const VENDOR_DLL = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_
const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache');
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
const IS_DEV_SERVER = process.env.WEBPACK_SERVE === 'true';
-const WEBPACK_USE_ESBUILD_LOADER =
- process.env.WEBPACK_USE_ESBUILD_LOADER && process.env.WEBPACK_USE_ESBUILD_LOADER !== 'false';
const { DEV_SERVER_HOST, DEV_SERVER_PUBLIC_ADDR } = process.env;
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10);
@@ -69,11 +64,9 @@ const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD
const INCREMENTAL_COMPILER_ENABLED =
IS_DEV_SERVER &&
process.env.DEV_SERVER_INCREMENTAL &&
- process.env.DEV_SERVER_INCREMENTAL !== 'false' &&
- !WEBPACK_USE_ESBUILD_LOADER;
+ process.env.DEV_SERVER_INCREMENTAL !== 'false';
const INCREMENTAL_COMPILER_TTL = Number(process.env.DEV_SERVER_INCREMENTAL_TTL) || Infinity;
-const INCREMENTAL_COMPILER_RECORD_HISTORY =
- IS_DEV_SERVER && !process.env.CI && !WEBPACK_USE_ESBUILD_LOADER;
+const INCREMENTAL_COMPILER_RECORD_HISTORY = IS_DEV_SERVER && !process.env.CI;
const WEBPACK_REPORT = process.env.WEBPACK_REPORT && process.env.WEBPACK_REPORT !== 'false';
const WEBPACK_MEMORY_TEST =
process.env.WEBPACK_MEMORY_TEST && process.env.WEBPACK_MEMORY_TEST !== 'false';
@@ -294,10 +287,6 @@ const defaultJsOptions = {
cacheCompression: false,
};
-if (WEBPACK_USE_ESBUILD_LOADER) {
- console.log('esbuild-loader is active');
-}
-
const vueLoaderOptions = {
ident: 'vue-loader-options',
@@ -374,13 +363,7 @@ module.exports = {
include: /node_modules/,
loader: 'babel-loader',
},
- WEBPACK_USE_ESBUILD_LOADER && {
- test: /\.(js|cjs)$/,
- exclude: shouldExcludeFromCompliling,
- loader: 'esbuild-loader',
- options: esbuildConfiguration,
- },
- !WEBPACK_USE_ESBUILD_LOADER && {
+ {
test: /\.(js|cjs)$/,
exclude: shouldExcludeFromCompliling,
use: [
@@ -399,16 +382,7 @@ module.exports = {
},
],
},
- WEBPACK_USE_ESBUILD_LOADER && {
- test: /\.(js|cjs)$/,
- include: (modulePath) =>
- /node_modules\/(monaco-worker-manager|monaco-marker-data-provider)\/index\.js/.test(
- modulePath,
- ) || /node_modules\/yaml/.test(modulePath),
- loader: 'esbuild-loader',
- options: esbuildConfiguration,
- },
- !WEBPACK_USE_ESBUILD_LOADER && {
+ {
test: /\.(js|cjs)$/,
include: (modulePath) =>
/node_modules\/(monaco-worker-manager|monaco-marker-data-provider)\/index\.js/.test(
@@ -586,7 +560,6 @@ module.exports = {
},
},
},
- ...(WEBPACK_USE_ESBUILD_LOADER ? { minimizer: [new EsbuildPlugin(esbuildConfiguration)] } : {}),
},
plugins: [
diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js
index a43febe5e25..b05e5a7cdef 100644
--- a/config/webpack.vendor.config.js
+++ b/config/webpack.vendor.config.js
@@ -76,8 +76,6 @@ module.exports = {
https://gitlab.com/gitlab-org/gitlab/-/issues/219353
*/
'chokidar',
- // We are ignoring esbuild as we want to force a newer version than what esbuild-loader provides
- 'esbuild',
// We are ignoring ts-jest, because we force a newer version, compatible with our current jest version
'ts-jest',
].join('|'),
diff --git a/db/post_migrate/20230320155635_add_index_to_namespace_details.rb b/db/post_migrate/20230320155635_add_index_to_namespace_details.rb
new file mode 100644
index 00000000000..de00c57836b
--- /dev/null
+++ b/db/post_migrate/20230320155635_add_index_to_namespace_details.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToNamespaceDetails < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_fuc_over_limit_notified_at'
+ TABLE_NAME = 'namespace_details'
+ COLUMN_NAME = 'free_user_cap_over_limit_notified_at'
+
+ def up
+ add_concurrent_index TABLE_NAME, COLUMN_NAME, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name TABLE_NAME, name: INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20230320155635 b/db/schema_migrations/20230320155635
new file mode 100644
index 00000000000..91ade579ffb
--- /dev/null
+++ b/db/schema_migrations/20230320155635
@@ -0,0 +1 @@
+58d91bbad9896429a0b8d383a1d5ef47a7b017c65af7834c01091fbccb7f5221
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 1a8e7e947c8..4b3f176feda 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -30335,6 +30335,8 @@ CREATE UNIQUE INDEX index_fork_network_members_on_project_id ON fork_network_mem
CREATE UNIQUE INDEX index_fork_networks_on_root_project_id ON fork_networks USING btree (root_project_id);
+CREATE INDEX index_fuc_over_limit_notified_at ON namespace_details USING btree (free_user_cap_over_limit_notified_at);
+
CREATE INDEX index_geo_event_log_on_cache_invalidation_event_id ON geo_event_log USING btree (cache_invalidation_event_id) WHERE (cache_invalidation_event_id IS NOT NULL);
CREATE INDEX index_geo_event_log_on_geo_event_id ON geo_event_log USING btree (geo_event_id) WHERE (geo_event_id IS NOT NULL);
diff --git a/doc/api/audit_events.md b/doc/api/audit_events.md
index f42ace8c1de..3c4f80fd52d 100644
--- a/doc/api/audit_events.md
+++ b/doc/api/audit_events.md
@@ -8,6 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/121) in GitLab 12.4.
> - [Author Email added to the response body](https://gitlab.com/gitlab-org/gitlab/-/issues/386322) in GitLab 15.9.
+> - Support for keyset pagination [added](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.11.
## Instance Audit Events **(PREMIUM SELF)**
@@ -29,8 +30,8 @@ GET /audit_events
| `entity_type` | string | no | Return audit events for the given entity type. Valid values are: `User`, `Group`, or `Project`. |
| `entity_id` | integer | no | Return audit events for the given entity ID. Requires `entity_type` attribute to be present. |
-By default, `GET` requests return 20 results at a time because the API results
-are paginated.
+This endpoint supports both offset-based and [keyset-based](rest/index.md#keyset-based-pagination) pagination. You should use keyset-based
+pagination when requesting consecutive pages of results.
Read more on [pagination](rest/index.md#pagination).
diff --git a/doc/api/rest/index.md b/doc/api/rest/index.md
index 91a70c3f2a9..51fea290e55 100644
--- a/doc/api/rest/index.md
+++ b/doc/api/rest/index.md
@@ -483,13 +483,14 @@ pagination headers.
Keyset-based pagination is supported only for selected resources and ordering
options:
-| Resource | Options | Availability |
-|:----------------------------------------------------------------|:---------------------------------|:--------------------------------------------------------------------------------------------------------------|
-| [Projects](../projects.md) | `order_by=id` only | Authenticated and unauthenticated users |
-| [Groups](../groups.md) | `order_by=name`, `sort=asc` only | Unauthenticated users only |
-| [Group audit events](../audit_events.md#group-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333968) in GitLab 15.2) |
-| [Project audit events](../audit_events.md#project-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.10) |
-| [Jobs](../jobs.md) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362172) in GitLab 15.9) |
+| Resource | Options | Availability |
+|:------------------------------------------------------------------|:---------------------------------|:--------------------------------------------------------------------------------------------------------------|
+| [Projects](../projects.md) | `order_by=id` only | Authenticated and unauthenticated users |
+| [Groups](../groups.md) | `order_by=name`, `sort=asc` only | Unauthenticated users only |
+| [Instance audit events](../audit_events.md#instance-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.11) |
+| [Group audit events](../audit_events.md#group-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333968) in GitLab 15.2) |
+| [Project audit events](../audit_events.md#project-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.10) |
+| [Jobs](../jobs.md) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362172) in GitLab 15.9) |
### Pagination response headers
diff --git a/lib/gitlab/graphql/project/dast_profile_connection_extension.rb b/lib/gitlab/graphql/project/dast_profile_connection_extension.rb
index 45f90de2f17..1c21d286187 100644
--- a/lib/gitlab/graphql/project/dast_profile_connection_extension.rb
+++ b/lib/gitlab/graphql/project/dast_profile_connection_extension.rb
@@ -12,9 +12,12 @@ module Gitlab
def preload_authorizations(dast_profiles)
return unless dast_profiles
- projects = dast_profiles.map(&:project)
- users = dast_profiles.filter_map { |dast_profile| dast_profile.dast_profile_schedule&.owner }
- Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
+ project_users = dast_profiles.group_by(&:project).transform_values do |project_profiles|
+ project_profiles
+ .filter_map { |profile| profile.dast_profile_schedule&.owner }
+ .uniq
+ end
+ Preloaders::UsersMaxAccessLevelByProjectPreloader.new(project_users: project_users).execute
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 31e94d1c47c..27c71915f97 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -50896,6 +50896,9 @@ msgstr ""
msgid "can not be changed to %{new_type}"
msgstr ""
+msgid "can not be changed when assigned to an epic"
+msgstr ""
+
msgid "can not be set for this resource"
msgstr ""
@@ -50959,6 +50962,12 @@ msgstr ""
msgid "cannot be changed since member is associated with a custom role"
msgstr ""
+msgid "cannot be changed to %{new_type} with %{parent_type} as parent type."
+msgstr ""
+
+msgid "cannot be changed to %{new_type} with these child item types."
+msgstr ""
+
msgid "cannot be enabled"
msgstr ""
diff --git a/package.json b/package.json
index f9299d66410..a13b2742e21 100644
--- a/package.json
+++ b/package.json
@@ -126,8 +126,6 @@
"dropzone": "^4.2.0",
"editorconfig": "^0.15.3",
"emoji-regex": "^10.0.0",
- "esbuild": "0.17.11",
- "esbuild-loader": "^3.0.1",
"fast-mersenne-twister": "1.0.2",
"file-loader": "^6.2.0",
"fuzzaldrin-plus": "^0.6.0",
diff --git a/spec/experiments/application_experiment_spec.rb b/spec/experiments/application_experiment_spec.rb
index 61c9fb5b4a4..ef8f8cbce3b 100644
--- a/spec/experiments/application_experiment_spec.rb
+++ b/spec/experiments/application_experiment_spec.rb
@@ -211,7 +211,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
application_experiment.variant(:variant1) {}
application_experiment.variant(:variant2) {}
- expect(application_experiment.assigned.name).to eq(:variant2)
+ expect(application_experiment.assigned.name).to eq('variant2')
end
end
@@ -248,7 +248,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
end
it "caches the variant determined by the variant resolver" do
- expect(application_experiment.assigned.name).to eq(:candidate) # we should be in the experiment
+ expect(application_experiment.assigned.name).to eq('candidate') # we should be in the experiment
application_experiment.run
@@ -263,7 +263,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
# the control.
stub_feature_flags(namespaced_stub: false) # simulate being not rolled out
- expect(application_experiment.assigned.name).to eq(:control) # if we ask, it should be control
+ expect(application_experiment.assigned.name).to eq('control') # if we ask, it should be control
application_experiment.run
@@ -299,4 +299,29 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
end
end
end
+
+ context "with deprecation warnings" do
+ before do
+ Gitlab::Experiment::Configuration.instance_variable_set(:@__dep_versions, nil) # clear the internal memoization
+
+ allow(ActiveSupport::Deprecation).to receive(:new).and_call_original
+ end
+
+ it "doesn't warn on non dev/test environments" do
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(false)
+
+ expect { experiment(:example) { |e| e.use {} } }.not_to raise_error
+ expect(ActiveSupport::Deprecation).not_to have_received(:new).with(anything, 'Gitlab::Experiment')
+ end
+
+ it "warns on dev and test environments" do
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(true)
+
+ # This will eventually raise an ActiveSupport::Deprecation exception,
+ # it's ok to change it when that happens.
+ expect { experiment(:example) { |e| e.use {} } }.not_to raise_error
+
+ expect(ActiveSupport::Deprecation).to have_received(:new).with(anything, 'Gitlab::Experiment')
+ end
+ end
end
diff --git a/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
index 9c6556745d7..ee02fa5f1f2 100644
--- a/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
+++ b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
@@ -4,6 +4,6 @@ require 'spec_helper'
RSpec.describe SecurityReportsMrWidgetPromptExperiment do
it "defines a control and candidate" do
- expect(subject.behaviors.keys).to match_array(%i[control candidate])
+ expect(subject.behaviors.keys).to match_array(%w[control candidate])
end
end
diff --git a/spec/lib/gitlab/experiment/rollout/feature_spec.rb b/spec/lib/gitlab/experiment/rollout/feature_spec.rb
index cd46e7b3386..a66f4fea207 100644
--- a/spec/lib/gitlab/experiment/rollout/feature_spec.rb
+++ b/spec/lib/gitlab/experiment/rollout/feature_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::Experiment::Rollout::Feature, :experiment do
- subject { described_class.new(subject_experiment) }
+ subject { described_class.new.for(subject_experiment) }
let(:subject_experiment) { experiment('namespaced/stub') }
diff --git a/spec/models/concerns/ci/partitionable/switch_spec.rb b/spec/models/concerns/ci/partitionable/switch_spec.rb
index d955ad223f8..551ae111fa4 100644
--- a/spec/models/concerns/ci/partitionable/switch_spec.rb
+++ b/spec/models/concerns/ci/partitionable/switch_spec.rb
@@ -59,13 +59,14 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do
model.include(Ci::Partitionable)
model.partitionable scope: ->(r) { 1 },
- through: { table: :_test_p_ci_jobs_metadata, flag: table_rollout_flag }
+ through: { table: :_test_p_ci_jobs_metadata, flag: table_rollout_flag }
model.belongs_to :job, anonymous_class: jobs_model
- jobs_model.has_one :metadata, anonymous_class: model,
- foreign_key: :job_id, inverse_of: :job,
- dependent: :destroy
+ jobs_model.has_one :metadata,
+ anonymous_class: model,
+ foreign_key: :job_id, inverse_of: :job,
+ dependent: :destroy
allow(Feature::Definition).to receive(:get).and_call_original
allow(Feature::Definition).to receive(:get).with(table_rollout_flag)
diff --git a/spec/models/concerns/ci/partitionable_spec.rb b/spec/models/concerns/ci/partitionable_spec.rb
index 5100f20ed25..d41654e547e 100644
--- a/spec/models/concerns/ci/partitionable_spec.rb
+++ b/spec/models/concerns/ci/partitionable_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Ci::Partitionable do
ci_model.include(described_class)
ci_model.partitionable scope: ->(r) { 1 },
- through: { table: :_test_table_name, flag: :some_flag }
+ through: { table: :_test_table_name, flag: :some_flag }
end
it { expect(ci_model.routing_table_name).to eq(:_test_table_name) }
diff --git a/spec/models/concerns/ci/track_environment_usage_spec.rb b/spec/models/concerns/ci/track_environment_usage_spec.rb
index d75972c49b5..ad89973eee5 100644
--- a/spec/models/concerns/ci/track_environment_usage_spec.rb
+++ b/spec/models/concerns/ci/track_environment_usage_spec.rb
@@ -8,10 +8,12 @@ RSpec.describe Ci::TrackEnvironmentUsage do
context 'when build is the verify action for the environment' do
let(:build) do
- build_stubbed(:ci_build,
- ref: 'master',
- environment: 'staging',
- options: { environment: { action: 'verify' } })
+ build_stubbed(
+ :ci_build,
+ ref: 'master',
+ environment: 'staging',
+ options: { environment: { action: 'verify' } }
+ )
end
it { is_expected.to be_truthy }
@@ -19,10 +21,12 @@ RSpec.describe Ci::TrackEnvironmentUsage do
context 'when build is not the verify action for the environment' do
let(:build) do
- build_stubbed(:ci_build,
- ref: 'master',
- environment: 'staging',
- options: { environment: { action: 'start' } })
+ build_stubbed(
+ :ci_build,
+ ref: 'master',
+ environment: 'staging',
+ options: { environment: { action: 'start' } }
+ )
end
it { is_expected.to be_falsey }
diff --git a/spec/models/concerns/database_event_tracking_spec.rb b/spec/models/concerns/database_event_tracking_spec.rb
index 976462b4174..87aa8275635 100644
--- a/spec/models/concerns/database_event_tracking_spec.rb
+++ b/spec/models/concerns/database_event_tracking_spec.rb
@@ -46,24 +46,42 @@ RSpec.describe DatabaseEventTracking, :snowplow do
it 'when created' do
create_test_class_record
- expect_snowplow_event(category: category, action: "#{event}_create", label: 'application_setting_terms',
- property: 'create', namespace: nil, "id" => 1)
+ expect_snowplow_event(
+ category: category,
+ action: "#{event}_create",
+ label: 'application_setting_terms',
+ property: 'create',
+ namespace: nil,
+ "id" => 1
+ )
end
it 'when updated' do
create_test_class_record
test_class.first.update!(id: 3)
- expect_snowplow_event(category: category, action: "#{event}_update", label: 'application_setting_terms',
- property: 'update', namespace: nil, "id" => 3)
+ expect_snowplow_event(
+ category: category,
+ action: "#{event}_update",
+ label: 'application_setting_terms',
+ property: 'update',
+ namespace: nil,
+ "id" => 3
+ )
end
it 'when destroyed' do
create_test_class_record
test_class.first.destroy!
- expect_snowplow_event(category: category, action: "#{event}_destroy", label: 'application_setting_terms',
- property: 'destroy', namespace: nil, "id" => 1)
+ expect_snowplow_event(
+ category: category,
+ action: "#{event}_destroy",
+ label: 'application_setting_terms',
+ property: 'destroy',
+ namespace: nil,
+ "id" => 1
+ )
end
end
end
diff --git a/spec/models/concerns/deployment_platform_spec.rb b/spec/models/concerns/deployment_platform_spec.rb
index bd1afe844ac..9b086e9785e 100644
--- a/spec/models/concerns/deployment_platform_spec.rb
+++ b/spec/models/concerns/deployment_platform_spec.rb
@@ -56,13 +56,23 @@ RSpec.describe DeploymentPlatform do
context 'when project does not have a cluster but has group clusters' do
let!(:default_cluster) do
- create(:cluster, :provided_by_user,
- cluster_type: :group_type, groups: [group], environment_scope: '*')
+ create(
+ :cluster,
+ :provided_by_user,
+ cluster_type: :group_type,
+ groups: [group],
+ environment_scope: '*'
+ )
end
let!(:cluster) do
- create(:cluster, :provided_by_user,
- cluster_type: :group_type, environment_scope: 'review/*', groups: [group])
+ create(
+ :cluster,
+ :provided_by_user,
+ cluster_type: :group_type,
+ environment_scope: 'review/*',
+ groups: [group]
+ )
end
let(:environment) { 'review/name' }
@@ -99,8 +109,13 @@ RSpec.describe DeploymentPlatform do
context 'when parent_group has a cluster with default scope' do
let!(:parent_group_cluster) do
- create(:cluster, :provided_by_user,
- cluster_type: :group_type, environment_scope: '*', groups: [parent_group])
+ create(
+ :cluster,
+ :provided_by_user,
+ cluster_type: :group_type,
+ environment_scope: '*',
+ groups: [parent_group]
+ )
end
it_behaves_like 'matching environment scope'
@@ -108,8 +123,13 @@ RSpec.describe DeploymentPlatform do
context 'when parent_group has a cluster that is an exact match' do
let!(:parent_group_cluster) do
- create(:cluster, :provided_by_user,
- cluster_type: :group_type, environment_scope: 'review/name', groups: [parent_group])
+ create(
+ :cluster,
+ :provided_by_user,
+ cluster_type: :group_type,
+ environment_scope: 'review/name',
+ groups: [parent_group]
+ )
end
it_behaves_like 'matching environment scope'
@@ -160,8 +180,13 @@ RSpec.describe DeploymentPlatform do
let!(:cluster) { create(:cluster, :provided_by_user, environment_scope: 'review/*', projects: [project]) }
let!(:group_default_cluster) do
- create(:cluster, :provided_by_user,
- cluster_type: :group_type, groups: [group], environment_scope: '*')
+ create(
+ :cluster,
+ :provided_by_user,
+ cluster_type: :group_type,
+ groups: [group],
+ environment_scope: '*'
+ )
end
let(:environment) { 'review/name' }
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 206b3ae61cf..ea6baac455f 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -150,8 +150,10 @@ RSpec.describe Issuable do
end
it 'gives preference to state_id if present' do
- issuable = MergeRequest.new('state' => 'opened',
- 'state_id' => described_class::STATE_ID_MAP['merged'])
+ issuable = MergeRequest.new(
+ 'state' => 'opened',
+ 'state_id' => described_class::STATE_ID_MAP['merged']
+ )
expect(issuable.state).to eq('merged')
expect(issuable.state_id).to eq(described_class::STATE_ID_MAP['merged'])
diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb
index e53fdafe3b1..7367577914c 100644
--- a/spec/models/concerns/token_authenticatable_spec.rb
+++ b/spec/models/concerns/token_authenticatable_spec.rb
@@ -130,10 +130,7 @@ RSpec.describe PersonalAccessToken, 'TokenAuthenticatable' do
let(:token_digest) { Gitlab::CryptoHelper.sha256(token_value) }
let(:user) { create(:user) }
let(:personal_access_token) do
- described_class.new(name: 'test-pat-01',
- user_id: user.id,
- scopes: [:api],
- token_digest: token_digest)
+ described_class.new(name: 'test-pat-01', user_id: user.id, scopes: [:api], token_digest: token_digest)
end
before do
diff --git a/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb b/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb
new file mode 100644
index 00000000000..f5bc0c8c2f8
--- /dev/null
+++ b/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Preloaders::UsersMaxAccessLevelByProjectPreloader, feature_category: :projects do
+ let_it_be(:user_1) { create(:user) }
+ let_it_be(:user_2) { create(:user) }
+ let_it_be(:user_with_no_access) { create(:user) } # ensures we correctly cache NO_ACCESS
+
+ let_it_be(:project_1) { create(:project) }
+ let_it_be(:project_2) { create(:project) }
+ let_it_be(:project_3) { create(:project) }
+
+ before do
+ project_1.add_developer(user_1)
+ project_1.add_developer(user_2)
+
+ project_2.add_developer(user_1)
+ project_2.add_developer(user_2)
+
+ project_3.add_developer(user_1)
+ project_3.add_developer(user_2)
+ end
+
+ describe '#execute', :request_store do
+ let(:project_users) do
+ {
+ project_1 => [user_1, user_with_no_access],
+ project_2 => user_2
+ }
+ end
+
+ it 'avoids N+1 queries' do
+ control_input = project_users
+ control = ActiveRecord::QueryRecorder.new do
+ described_class.new(project_users: control_input).execute
+ end
+
+ sample_input = control_input.merge(project_3 => user_2)
+ sample = ActiveRecord::QueryRecorder.new do
+ described_class.new(project_users: sample_input).execute
+ end
+
+ expect(sample).not_to exceed_query_limit(control)
+ end
+
+ it 'preloads the max access level used by project policies' do
+ described_class.new(project_users: project_users).execute
+
+ policy_queries = ActiveRecord::QueryRecorder.new do
+ project_users.each do |project, users|
+ Array.wrap(users).each do |user|
+ user.can?(:read_project, project)
+ end
+ end
+ end
+
+ expect(policy_queries).not_to exceed_query_limit(0)
+ end
+ end
+end
diff --git a/spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb b/spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb
deleted file mode 100644
index 7ecb6bb9861..00000000000
--- a/spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-RSpec.describe Preloaders::UsersMaxAccessLevelInProjectsPreloader do
- let_it_be(:user1) { create(:user) }
- let_it_be(:user2) { create(:user) }
-
- let_it_be(:project_1) { create(:project) }
- let_it_be(:project_2) { create(:project) }
- let_it_be(:project_3) { create(:project) }
-
- let(:projects) { [project_1, project_2, project_3] }
- let(:users) { [user1, user2] }
-
- before do
- project_1.add_developer(user1)
- project_1.add_developer(user2)
-
- project_2.add_developer(user1)
- project_2.add_developer(user2)
-
- project_3.add_developer(user1)
- project_3.add_developer(user2)
- end
-
- context 'preload maximum access level to avoid querying project_authorizations', :request_store do
- it 'avoids N+1 queries', :request_store do
- Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
-
- expect(count_queries).to eq(0)
- end
-
- it 'runs N queries without preloading' do
- query_count_without_preload = count_queries
-
- Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
- count_queries_with_preload = count_queries
-
- expect(count_queries_with_preload).to be < query_count_without_preload
- end
- end
-
- def count_queries
- ActiveRecord::QueryRecorder.new do
- projects.each do |project|
- user1.can?(:read_project, project)
- user2.can?(:read_project, project)
- end
- end.count
- end
-end
diff --git a/spec/models/work_item_spec.rb b/spec/models/work_item_spec.rb
index 13f17e11276..c2e1c72181d 100644
--- a/spec/models/work_item_spec.rb
+++ b/spec/models/work_item_spec.rb
@@ -368,4 +368,179 @@ RSpec.describe WorkItem, feature_category: :portfolio_management do
end
end
end
+
+ describe '#allowed_work_item_type_change' do
+ let_it_be(:all_types) { WorkItems::Type::BASE_TYPES.keys }
+
+ it 'is possible to change between all types', :aggregate_failures do
+ all_types.each do |type|
+ work_item = build(:work_item, type, project: reusable_project)
+
+ (all_types - [type]).each do |new_type|
+ work_item.work_item_type_id = WorkItems::Type.default_by_type(new_type).id
+
+ expect(work_item).to be_valid, "#{type} to #{new_type}"
+ end
+ end
+ end
+
+ context 'with ParentLink relation' do
+ let_it_be(:old_type) { create(:work_item_type) }
+ let_it_be(:new_type) { create(:work_item_type) }
+
+ context 'with hierarchy restrictions' do
+ let_it_be(:child_type) { create(:work_item_type) }
+
+ let_it_be_with_reload(:parent) { create(:work_item, work_item_type: old_type, project: reusable_project) }
+ let_it_be_with_reload(:child) { create(:work_item, work_item_type: child_type, project: reusable_project) }
+
+ let_it_be(:hierarchy_restriction) do
+ create(:hierarchy_restriction, parent_type: old_type, child_type: child_type)
+ end
+
+ let_it_be(:link) { create(:parent_link, work_item_parent: parent, work_item: child) }
+
+ context 'when child items restrict the type change' do
+ before do
+ parent.work_item_type = new_type
+ end
+
+ context 'when child items are compatible with the new type' do
+ let_it_be(:hierarchy_restriction_new_type) do
+ create(:hierarchy_restriction, parent_type: new_type, child_type: child_type)
+ end
+
+ it 'allows to change types' do
+ expect(parent).to be_valid
+ expect(parent.errors).to be_empty
+ end
+ end
+
+ context 'when child items are not compatible with the new type' do
+ it 'does not allow to change types' do
+ expect(parent).not_to be_valid
+ expect(parent.errors[:work_item_type_id])
+ .to include("cannot be changed to #{new_type.name} with these child item types.")
+ end
+ end
+ end
+
+ context 'when the parent restricts the type change' do
+ before do
+ child.work_item_type = new_type
+ end
+
+ it 'does not allow to change types' do
+ expect(child.valid?).to eq(false)
+ expect(child.errors[:work_item_type_id])
+ .to include("cannot be changed to #{new_type.name} with #{parent.work_item_type.name} as parent type.")
+ end
+ end
+ end
+
+ context 'with hierarchy depth restriction' do
+ let_it_be_with_reload(:item1) { create(:work_item, work_item_type: new_type, project: reusable_project) }
+ let_it_be_with_reload(:item2) { create(:work_item, work_item_type: new_type, project: reusable_project) }
+ let_it_be_with_reload(:item3) { create(:work_item, work_item_type: new_type, project: reusable_project) }
+ let_it_be_with_reload(:item4) { create(:work_item, work_item_type: new_type, project: reusable_project) }
+
+ let_it_be(:hierarchy_restriction1) do
+ create(:hierarchy_restriction, parent_type: old_type, child_type: new_type)
+ end
+
+ let_it_be(:hierarchy_restriction2) do
+ create(:hierarchy_restriction, parent_type: new_type, child_type: old_type)
+ end
+
+ let_it_be_with_reload(:hierarchy_restriction3) do
+ create(:hierarchy_restriction, parent_type: new_type, child_type: new_type, maximum_depth: 4)
+ end
+
+ let_it_be(:link1) { create(:parent_link, work_item_parent: item1, work_item: item2) }
+ let_it_be(:link2) { create(:parent_link, work_item_parent: item2, work_item: item3) }
+ let_it_be(:link3) { create(:parent_link, work_item_parent: item3, work_item: item4) }
+
+ before do
+ hierarchy_restriction3.update!(maximum_depth: maximum_depth)
+ end
+
+ shared_examples 'validates the depth correctly' do
+ before do
+ work_item.update!(work_item_type: old_type)
+ end
+
+ context 'when it is valid' do
+ let(:maximum_depth) { 4 }
+
+ it 'allows to change types' do
+ work_item.work_item_type = new_type
+
+ expect(work_item).to be_valid
+ end
+ end
+
+ context 'when it is not valid' do
+ let(:maximum_depth) { 3 }
+
+ it 'does not allow to change types' do
+ work_item.work_item_type = new_type
+
+ expect(work_item).not_to be_valid
+ expect(work_item.errors[:work_item_type_id]).to include("reached maximum depth")
+ end
+ end
+ end
+
+ context 'with the highest ancestor' do
+ let_it_be_with_reload(:work_item) { item1 }
+
+ it_behaves_like 'validates the depth correctly'
+ end
+
+ context 'with a child item' do
+ let_it_be_with_reload(:work_item) { item2 }
+
+ it_behaves_like 'validates the depth correctly'
+ end
+
+ context 'with the last child item' do
+ let_it_be_with_reload(:work_item) { item4 }
+
+ it_behaves_like 'validates the depth correctly'
+ end
+
+ context 'when ancestor is still the old type' do
+ let_it_be(:hierarchy_restriction4) do
+ create(:hierarchy_restriction, parent_type: old_type, child_type: old_type)
+ end
+
+ before do
+ item1.update!(work_item_type: old_type)
+ item2.update!(work_item_type: old_type)
+ end
+
+ context 'when it exceeds maximum depth' do
+ let(:maximum_depth) { 2 }
+
+ it 'does not allow to change types' do
+ item2.work_item_type = new_type
+
+ expect(item2).not_to be_valid
+ expect(item2.errors[:work_item_type_id]).to include("reached maximum depth")
+ end
+ end
+
+ context 'when it does not exceed maximum depth' do
+ let(:maximum_depth) { 3 }
+
+ it 'does allow to change types' do
+ item2.work_item_type = new_type
+
+ expect(item2).to be_valid
+ end
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 12a6553f51a..391393278ef 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when invalid' do
shared_examples 'invalid file upload request' do
- it 'returns 400' do
+ it 'returns 400', :aggregate_failures do
make_upload_request
expect(response).to have_gitlab_http_status(:bad_request)
@@ -65,7 +65,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
shared_examples 'skips searching in full path' do
- it 'does not find groups by full path' do
+ it 'does not find groups by full path', :aggregate_failures do
subgroup = create(:group, parent: parent, path: "#{parent.path}-subgroup")
create(:group, parent: parent, path: 'not_matching_path')
@@ -79,7 +79,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
describe "GET /groups" do
context "when unauthenticated" do
- it "returns public groups" do
+ it "returns public groups", :aggregate_failures do
get api("/groups")
expect(response).to have_gitlab_http_status(:ok)
@@ -93,18 +93,18 @@ RSpec.describe API::Groups, feature_category: :subgroups do
it 'avoids N+1 queries', :use_sql_query_cache do
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
- get api("/groups", admin)
+ get api("/groups")
end
create(:group)
expect do
- get api("/groups", admin)
+ get api("/groups")
end.not_to exceed_all_query_limit(control)
end
context 'when statistics are requested' do
- it 'does not include statistics' do
+ it 'does not include statistics', :aggregate_failures do
get api("/groups"), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -116,7 +116,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as user" do
- it "normal user: returns an array of groups of user1" do
+ it "normal user: returns an array of groups of user1", :aggregate_failures do
get api("/groups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -127,7 +127,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
.to satisfy_one { |group| group['name'] == group1.name }
end
- it "does not include runners_token information" do
+ it "does not include runners_token information", :aggregate_failures do
get api("/groups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -137,7 +137,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first).not_to include('runners_token')
end
- it "does not include statistics" do
+ it "does not include statistics", :aggregate_failures do
get api("/groups", user1), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -146,7 +146,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first).not_to include 'statistics'
end
- it "includes a created_at timestamp" do
+ it "includes a created_at timestamp", :aggregate_failures do
get api("/groups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -175,7 +175,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'on making requests below the allowed offset pagination threshold' do
- it 'paginates the records' do
+ it 'paginates the records', :aggregate_failures do
get api('/groups'), params: { page: 1, per_page: 1 }
expect(response).to have_gitlab_http_status(:ok)
@@ -214,7 +214,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'on making requests with supported ordering structure' do
- it 'paginates the records correctly' do
+ it 'paginates the records correctly', :aggregate_failures do
# first page
get api('/groups'), params: { pagination: 'keyset', per_page: 1 }
@@ -236,7 +236,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'on making requests with unsupported ordering structure' do
- it 'returns error' do
+ it 'returns error', :aggregate_failures do
get api('/groups'), params: { pagination: 'keyset', per_page: 1, order_by: 'path', sort: 'desc' }
expect(response).to have_gitlab_http_status(:method_not_allowed)
@@ -248,8 +248,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as admin" do
- it "admin: returns an array of all groups" do
- get api("/groups", admin)
+ it "admin: returns an array of all groups", :aggregate_failures do
+ get api("/groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -257,8 +257,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.length).to eq(2)
end
- it "does not include runners_token information" do
- get api("/groups", admin)
+ it "does not include runners_token information", :aggregate_failures do
+ get api("/groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -267,8 +267,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first).not_to include('runners_token')
end
- it "does not include statistics by default" do
- get api("/groups", admin)
+ it "does not include statistics by default", :aggregate_failures do
+ get api("/groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -276,8 +276,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first).not_to include('statistics')
end
- it "includes a created_at timestamp" do
- get api("/groups", admin)
+ it "includes a created_at timestamp", :aggregate_failures do
+ get api("/groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -285,7 +285,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['created_at']).to be_present
end
- it "includes statistics if requested" do
+ it "includes statistics if requested", :aggregate_failures do
attributes = {
storage_size: 4093,
repository_size: 123,
@@ -302,7 +302,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
project1.statistics.update!(attributes)
- get api("/groups", admin), params: { statistics: true }
+ get api("/groups", admin, admin_mode: true), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -313,8 +313,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when using skip_groups in request" do
- it "returns all groups excluding skipped groups" do
- get api("/groups", admin), params: { skip_groups: [group2.id] }
+ it "returns all groups excluding skipped groups", :aggregate_failures do
+ get api("/groups", admin, admin_mode: true), params: { skip_groups: [group2.id] }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -326,7 +326,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context "when using all_available in request" do
let(:response_groups) { json_response.map { |group| group['name'] } }
- it "returns all groups you have access to" do
+ it "returns all groups you have access to", :aggregate_failures do
public_group = create :group, :public
get api("/groups", user1), params: { all_available: true }
@@ -348,7 +348,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
subgroup.add_owner(user1)
end
- it "doesn't return subgroups" do
+ it "doesn't return subgroups", :aggregate_failures do
get api("/groups", user1), params: { top_level_only: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -373,7 +373,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group5.add_owner(user1)
end
- it "sorts by name ascending by default" do
+ it "sorts by name ascending by default", :aggregate_failures do
get api("/groups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -382,7 +382,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups).to eq(groups_visible_to_user(user1).order(:name).pluck(:name))
end
- it "sorts in descending order when passed" do
+ it "sorts in descending order when passed", :aggregate_failures do
get api("/groups", user1), params: { sort: "desc" }
expect(response).to have_gitlab_http_status(:ok)
@@ -391,7 +391,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups).to eq(groups_visible_to_user(user1).order(name: :desc).pluck(:name))
end
- it "sorts by path in order_by param" do
+ it "sorts by path in order_by param", :aggregate_failures do
get api("/groups", user1), params: { order_by: "path" }
expect(response).to have_gitlab_http_status(:ok)
@@ -400,7 +400,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups).to eq(groups_visible_to_user(user1).order(:path).pluck(:name))
end
- it "sorts by id in the order_by param" do
+ it "sorts by id in the order_by param", :aggregate_failures do
get api("/groups", user1), params: { order_by: "id" }
expect(response).to have_gitlab_http_status(:ok)
@@ -409,7 +409,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups).to eq(groups_visible_to_user(user1).order(:id).pluck(:name))
end
- it "sorts also by descending id with pagination fix" do
+ it "sorts also by descending id with pagination fix", :aggregate_failures do
get api("/groups", user1), params: { order_by: "id", sort: "desc" }
expect(response).to have_gitlab_http_status(:ok)
@@ -418,7 +418,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups).to eq(groups_visible_to_user(user1).order(id: :desc).pluck(:name))
end
- it "sorts identical keys by id for good pagination" do
+ it "sorts identical keys by id for good pagination", :aggregate_failures do
get api("/groups", user1), params: { search: "same-name", order_by: "name" }
expect(response).to have_gitlab_http_status(:ok)
@@ -427,7 +427,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response_groups_ids).to eq(Group.select { |group| group['name'] == 'same-name' }.map { |group| group['id'] }.sort)
end
- it "sorts descending identical keys by id for good pagination" do
+ it "sorts descending identical keys by id for good pagination", :aggregate_failures do
get api("/groups", user1), params: { search: "same-name", order_by: "name", sort: "desc" }
expect(response).to have_gitlab_http_status(:ok)
@@ -449,7 +449,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
subject { get api('/groups', user1), params: params }
- it 'sorts top level groups before subgroups with exact matches first' do
+ it 'sorts top level groups before subgroups with exact matches first', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -462,7 +462,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when `search` parameter is not given' do
let(:params) { { order_by: 'similarity' } }
- it 'sorts items ordered by name' do
+ it 'sorts items ordered by name', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -480,7 +480,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when using owned in the request' do
- it 'returns an array of groups the user owns' do
+ it 'returns an array of groups the user owns', :aggregate_failures do
group1.add_maintainer(user2)
get api('/groups', user2), params: { owned: true }
@@ -503,7 +503,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'with min_access_level parameter' do
- it 'returns an array of groups the user has at least master access' do
+ it 'returns an array of groups the user has at least master access', :aggregate_failures do
get api('/groups', user2), params: { min_access_level: 40 }
expect(response).to have_gitlab_http_status(:ok)
@@ -541,7 +541,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
subject { get api('/groups', user1), params: { search: group1.path } }
- it 'finds also groups with full path matching search param' do
+ it 'finds also groups with full path matching search param', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -587,7 +587,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response).to have_gitlab_http_status(:not_found)
end
- it 'returns 200 for a public group' do
+ it 'returns 200 for a public group', :aggregate_failures do
get api("/groups/#{group1.id}")
expect(response).to have_gitlab_http_status(:ok)
@@ -617,7 +617,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as user" do
- it "returns one of user1's groups" do
+ it "returns one of user1's groups", :aggregate_failures do
project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
group = create(:group)
@@ -661,7 +661,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response['shared_projects'][0]['id']).to eq(project.id)
end
- it "returns one of user1's groups without projects when with_projects option is set to false" do
+ it "returns one of user1's groups without projects when with_projects option is set to false", :aggregate_failures do
project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
@@ -673,14 +673,14 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response).not_to include('runners_token')
end
- it "doesn't return runners_token if the user is not the owner of the group" do
+ it "doesn't return runners_token if the user is not the owner of the group", :aggregate_failures do
get api("/groups/#{group1.id}", user3)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to include('runners_token')
end
- it "returns runners_token if the user is the owner of the group" do
+ it "returns runners_token if the user is the owner of the group", :aggregate_failures do
group1.add_owner(user3)
get api("/groups/#{group1.id}", user3)
@@ -720,8 +720,9 @@ RSpec.describe API::Groups, feature_category: :subgroups do
.to contain_exactly(projects[:public].id, projects[:internal].id)
end
- it 'avoids N+1 queries with project links' do
+ it 'avoids N+1 queries with project links', :aggregate_failures do
get api("/groups/#{group1.id}", user1)
+ expect(response).to have_gitlab_http_status(:ok)
control_count = ActiveRecord::QueryRecorder.new do
get api("/groups/#{group1.id}", user1)
@@ -754,25 +755,25 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as admin" do
- it "returns any existing group" do
- get api("/groups/#{group2.id}", admin)
+ it "returns any existing group", :aggregate_failures do
+ get api("/groups/#{group2.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(group2.name)
end
- it "returns information of the runners_token for the group" do
- get api("/groups/#{group2.id}", admin)
+ it "returns information of the runners_token for the group", :aggregate_failures do
+ get api("/groups/#{group2.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to include('runners_token')
end
- it "returns runners_token and no projects when with_projects option is set to false" do
+ it "returns runners_token and no projects when with_projects option is set to false", :aggregate_failures do
project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
- get api("/groups/#{group2.id}", admin), params: { with_projects: false }
+ get api("/groups/#{group2.id}", admin, admin_mode: true), params: { with_projects: false }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['projects']).to be_nil
@@ -781,14 +782,14 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
it "does not return a non existing group" do
- get api("/groups/#{non_existing_record_id}", admin)
+ get api("/groups/#{non_existing_record_id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when using group path in URL' do
- it 'returns any existing group' do
+ it 'returns any existing group', :aggregate_failures do
get api("/groups/#{group1.path}", admin)
expect(response).to have_gitlab_http_status(:ok)
@@ -796,7 +797,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
it 'does not return a non existing group' do
- get api('/groups/unknown', admin)
+ get api('/groups/unknown', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -826,7 +827,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it 'limits projects and shared_projects' do
+ it 'limits projects and shared_projects', :aggregate_failures do
get api("/groups/#{group1.id}")
expect(json_response['projects'].count).to eq(limit)
@@ -843,8 +844,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
subject(:shared_with_groups) { json_response['shared_with_groups'].map { _1['group_id']} }
context 'when authenticated as admin' do
- it 'returns all groups that share the group' do
- get api("/groups/#{shared_group.id}", admin)
+ it 'returns all groups that share the group', :aggregate_failures do
+ get api("/groups/#{shared_group.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id, group_link_2.shared_with_group_id)
@@ -852,7 +853,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when unauthenticated' do
- it 'returns only public groups that share the group' do
+ it 'returns only public groups that share the group', :aggregate_failures do
get api("/groups/#{shared_group.id}")
expect(response).to have_gitlab_http_status(:ok)
@@ -861,7 +862,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as a member of a parent group that has shared the group' do
- it 'returns private group if direct member' do
+ it 'returns private group if direct member', :aggregate_failures do
group2_sub.add_guest(user3)
get api("/groups/#{shared_group.id}", user3)
@@ -870,7 +871,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id, group_link_2.shared_with_group_id)
end
- it 'returns private group if inherited member' do
+ it 'returns private group if inherited member', :aggregate_failures do
inherited_guest_member = create(:user)
group2.add_guest(inherited_guest_member)
@@ -902,7 +903,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as the group owner' do
- it 'updates the group' do
+ it 'updates the group', :aggregate_failures do
workhorse_form_with_file(
api("/groups/#{group1.id}", user1),
method: :put,
@@ -942,7 +943,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response['prevent_sharing_groups_outside_hierarchy']).to eq(true)
end
- it 'removes the group avatar' do
+ it 'removes the group avatar', :aggregate_failures do
put api("/groups/#{group1.id}", user1), params: { avatar: '' }
aggregate_failures "testing response" do
@@ -952,7 +953,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it 'does not update visibility_level if it is restricted' do
+ it 'does not update visibility_level if it is restricted', :aggregate_failures do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
put api("/groups/#{group1.id}", user1), params: { visibility: 'internal' }
@@ -967,7 +968,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'for users who have the ability to update default_branch_protection' do
- it 'updates the attribute' do
+ it 'updates the attribute', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -976,7 +977,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'for users who does not have the ability to update default_branch_protection`' do
- it 'does not update the attribute' do
+ it 'does not update the attribute', :aggregate_failures do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user1, :update_default_branch_protection, group1) { false }
@@ -1016,21 +1017,21 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group3.add_owner(user3)
end
- it 'does not change visibility when not requested' do
+ it 'does not change visibility when not requested', :aggregate_failures do
put api("/groups/#{group3.id}", user3), params: { description: 'Bug #23083' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['visibility']).to eq('public')
end
- it 'prevents making private a group containing public subgroups' do
+ it 'prevents making private a group containing public subgroups', :aggregate_failures do
put api("/groups/#{group3.id}", user3), params: { visibility: 'private' }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']['visibility_level']).to contain_exactly('private is not allowed since there are sub-groups with higher visibility.')
end
- it 'does not update prevent_sharing_groups_outside_hierarchy' do
+ it 'does not update prevent_sharing_groups_outside_hierarchy', :aggregate_failures do
put api("/groups/#{subgroup.id}", user3), params: { description: 'it works', prevent_sharing_groups_outside_hierarchy: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1042,17 +1043,17 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as the admin' do
- it 'updates the group' do
- put api("/groups/#{group1.id}", admin), params: { name: new_group_name }
+ it 'updates the group', :aggregate_failures do
+ put api("/groups/#{group1.id}", admin, admin_mode: true), params: { name: new_group_name }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(new_group_name)
end
- it 'ignores visibility level restrictions' do
+ it 'ignores visibility level restrictions', :aggregate_failures do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
- put api("/groups/#{group1.id}", admin), params: { visibility: 'internal' }
+ put api("/groups/#{group1.id}", admin, admin_mode: true), params: { visibility: 'internal' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['visibility']).to eq('internal')
@@ -1094,7 +1095,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it "returns the group's projects" do
+ it "returns the group's projects", :aggregate_failures do
get api("/groups/#{group1.id}/projects", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1106,7 +1107,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'and using archived' do
- it "returns the group's archived projects" do
+ it "returns the group's archived projects", :aggregate_failures do
get api("/groups/#{group1.id}/projects?archived=true", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1116,7 +1117,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.map { |project| project['id'] }).to include(archived_project.id)
end
- it "returns the group's non-archived projects" do
+ it "returns the group's non-archived projects", :aggregate_failures do
get api("/groups/#{group1.id}/projects?archived=false", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1126,7 +1127,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.map { |project| project['id'] }).not_to include(archived_project.id)
end
- it "returns all of the group's projects" do
+ it "returns all of the group's projects", :aggregate_failures do
get api("/groups/#{group1.id}/projects", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1150,7 +1151,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group_with_projects.add_owner(user1)
end
- it 'returns items based ordered by similarity' do
+ it 'returns items based ordered by similarity', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1166,7 +1167,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
params.delete(:search)
end
- it 'returns items ordered by name' do
+ it 'returns items ordered by name', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1179,7 +1180,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it "returns the group's projects with simple representation" do
+ it "returns the group's projects with simple representation", :aggregate_failures do
get api("/groups/#{group1.id}/projects", user1), params: { simple: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1190,7 +1191,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['visibility']).not_to be_present
end
- it "filters the groups projects" do
+ it "filters the groups projects", :aggregate_failures do
public_project = create(:project, :public, path: 'test1', group: group1)
get api("/groups/#{group1.id}/projects", user1), params: { visibility: 'public' }
@@ -1202,7 +1203,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['name']).to eq(public_project.name)
end
- it "returns projects excluding shared" do
+ it "returns projects excluding shared", :aggregate_failures do
create(:project_group_link, project: create(:project), group: group1)
create(:project_group_link, project: create(:project), group: group1)
create(:project_group_link, project: create(:project), group: group1)
@@ -1227,7 +1228,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group1.reload
end
- it "returns projects including those in subgroups" do
+ it "returns projects including those in subgroups", :aggregate_failures do
get api("/groups/#{group1.id}/projects", user1), params: { include_subgroups: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1236,7 +1237,10 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.length).to eq(6)
end
- it 'avoids N+1 queries', :use_sql_query_cache, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/383788' do
+ it 'avoids N+1 queries', :aggregate_failures, :use_sql_query_cache, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/383788' do
+ get api("/groups/#{group1.id}/projects", user1), params: { include_subgroups: true }
+ expect(respone).to have_gitlab_http_status(:ok)
+
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get api("/groups/#{group1.id}/projects", user1), params: { include_subgroups: true }
end
@@ -1250,7 +1254,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when include_ancestor_groups is true' do
- it 'returns ancestors groups projects' do
+ it 'returns ancestors groups projects', :aggregate_failures do
subgroup = create(:group, parent: group1)
subgroup_project = create(:project, group: subgroup)
@@ -1275,7 +1279,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response).to have_gitlab_http_status(:not_found)
end
- it "only returns projects to which user has access" do
+ it "only returns projects to which user has access", :aggregate_failures do
project3.add_developer(user3)
get api("/groups/#{group1.id}/projects", user3)
@@ -1286,7 +1290,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['name']).to eq(project3.name)
end
- it 'only returns the projects owned by user' do
+ it 'only returns the projects owned by user', :aggregate_failures do
project2.group.add_owner(user3)
get api("/groups/#{project2.group.id}/projects", user3), params: { owned: true }
@@ -1296,7 +1300,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['name']).to eq(project2.name)
end
- it 'only returns the projects starred by user' do
+ it 'only returns the projects starred by user', :aggregate_failures do
user1.starred_projects = [project1]
get api("/groups/#{group1.id}/projects", user1), params: { starred: true }
@@ -1306,8 +1310,9 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['name']).to eq(project1.name)
end
- it 'avoids N+1 queries' do
+ it 'avoids N+1 queries', :aggregate_failures do
get api("/groups/#{group1.id}/projects", user1)
+ expect(response).to have_gitlab_http_status(:ok)
control_count = ActiveRecord::QueryRecorder.new do
get api("/groups/#{group1.id}/projects", user1)
@@ -1322,8 +1327,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as admin" do
- it "returns any existing group" do
- get api("/groups/#{group2.id}/projects", admin)
+ it "returns any existing group", :aggregate_failures do
+ get api("/groups/#{group2.id}/projects", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -1332,15 +1337,15 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
it "does not return a non existing group" do
- get api("/groups/#{non_existing_record_id}/projects", admin)
+ get api("/groups/#{non_existing_record_id}/projects", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when using group path in URL' do
- it 'returns any existing group' do
- get api("/groups/#{group1.path}/projects", admin)
+ it 'returns any existing group', :aggregate_failures do
+ get api("/groups/#{group1.path}/projects", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -1349,7 +1354,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
it 'does not return a non existing group' do
- get api('/groups/unknown/projects', admin)
+ get api('/groups/unknown/projects', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -1375,7 +1380,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as user' do
- it 'returns the shared projects in the group' do
+ it 'returns the shared projects in the group', :aggregate_failures do
get api(path, user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1386,7 +1391,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['visibility']).to be_present
end
- it 'returns shared projects with min access level or higher' do
+ it 'returns shared projects with min access level or higher', :aggregate_failures do
user = create(:user)
project2.add_guest(user)
@@ -1399,7 +1404,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['id']).to eq(project4.id)
end
- it 'returns the shared projects of the group with simple representation' do
+ it 'returns the shared projects of the group with simple representation', :aggregate_failures do
get api(path, user1), params: { simple: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1410,7 +1415,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['visibility']).not_to be_present
end
- it 'filters the shared projects in the group based on visibility' do
+ it 'filters the shared projects in the group based on visibility', :aggregate_failures do
internal_project = create(:project, :internal, namespace: create(:group))
create(:project_group_link, project: internal_project, group: group1)
@@ -1424,7 +1429,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['id']).to eq(internal_project.id)
end
- it 'filters the shared projects in the group based on search params' do
+ it 'filters the shared projects in the group based on search params', :aggregate_failures do
get api(path, user1), params: { search: 'test_project' }
expect(response).to have_gitlab_http_status(:ok)
@@ -1434,7 +1439,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['id']).to eq(project4.id)
end
- it 'does not return the projects owned by the group' do
+ it 'does not return the projects owned by the group', :aggregate_failures do
get api(path, user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1459,7 +1464,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response).to have_gitlab_http_status(:not_found)
end
- it 'only returns shared projects to which user has access' do
+ it 'only returns shared projects to which user has access', :aggregate_failures do
project4.add_developer(user3)
get api(path, user3)
@@ -1470,7 +1475,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response.first['id']).to eq(project4.id)
end
- it 'only returns the projects starred by user' do
+ it 'only returns the projects starred by user', :aggregate_failures do
user1.starred_projects = [project2]
get api(path, user1), params: { starred: true }
@@ -1482,9 +1487,9 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as admin" do
- subject { get api(path, admin) }
+ subject { get api(path, admin, admin_mode: true) }
- it "returns shared projects of an existing group" do
+ it "returns shared projects of an existing group", :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1504,7 +1509,10 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it 'avoids N+1 queries' do
+ it 'avoids N+1 queries', :aggregate_failures, :use_sql_query_cache do
+ subject
+ expect(response).to have_gitlab_http_status(:ok)
+
control_count = ActiveRecord::QueryRecorder.new do
subject
end.count
@@ -1520,8 +1528,8 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when using group path in URL' do
let(:path) { "/groups/#{group1.path}/projects/shared" }
- it 'returns the right details' do
- get api(path, admin)
+ it 'returns the right details', :aggregate_failures do
+ get api(path, admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -1531,7 +1539,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
it 'returns 404 for a non-existent group' do
- get api('/groups/unknown/projects/shared', admin)
+ get api('/groups/unknown/projects/shared', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -1544,7 +1552,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
let!(:subgroup3) { create(:group, :private, parent: group2) }
context 'when unauthenticated' do
- it 'returns only public subgroups' do
+ it 'returns only public subgroups', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups")
expect(response).to have_gitlab_http_status(:ok)
@@ -1562,7 +1570,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when statistics are requested' do
- it 'does not include statistics' do
+ it 'does not include statistics', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups"), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1575,7 +1583,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when authenticated as user' do
context 'when user is not member of a public group' do
- it 'returns no subgroups for the public group' do
+ it 'returns no subgroups for the public group', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups", user2)
expect(response).to have_gitlab_http_status(:ok)
@@ -1584,7 +1592,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when using all_available in request' do
- it 'returns public subgroups' do
+ it 'returns public subgroups', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups", user2), params: { all_available: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1609,7 +1617,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group1.add_guest(user2)
end
- it 'returns private subgroups' do
+ it 'returns private subgroups', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups", user2)
expect(response).to have_gitlab_http_status(:ok)
@@ -1623,7 +1631,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when using statistics in request' do
- it 'does not include statistics' do
+ it 'does not include statistics', :aggregate_failures do
get api("/groups/#{group1.id}/subgroups", user2), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1638,7 +1646,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group2.add_guest(user1)
end
- it 'returns subgroups' do
+ it 'returns subgroups', :aggregate_failures do
get api("/groups/#{group2.id}/subgroups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1651,32 +1659,32 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as admin' do
- it 'returns private subgroups of a public group' do
- get api("/groups/#{group1.id}/subgroups", admin)
+ it 'returns private subgroups of a public group', :aggregate_failures do
+ get api("/groups/#{group1.id}/subgroups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
- it 'returns subgroups of a private group' do
- get api("/groups/#{group2.id}/subgroups", admin)
+ it 'returns subgroups of a private group', :aggregate_failures do
+ get api("/groups/#{group2.id}/subgroups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
end
- it 'does not include statistics by default' do
- get api("/groups/#{group1.id}/subgroups", admin)
+ it 'does not include statistics by default', :aggregate_failures do
+ get api("/groups/#{group1.id}/subgroups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
end
- it 'includes statistics if requested' do
- get api("/groups/#{group1.id}/subgroups", admin), params: { statistics: true }
+ it 'includes statistics if requested', :aggregate_failures do
+ get api("/groups/#{group1.id}/subgroups", admin, admin_mode: true), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
@@ -1700,7 +1708,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
let(:response_groups) { json_response.map { |group| group['name'] } }
context 'when unauthenticated' do
- it 'returns only public descendants' do
+ it 'returns only public descendants', :aggregate_failures do
get api("/groups/#{group1.id}/descendant_groups")
expect(response).to have_gitlab_http_status(:ok)
@@ -1719,7 +1727,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when authenticated as user' do
context 'when user is not member of a public group' do
- it 'returns no descendants for the public group' do
+ it 'returns no descendants for the public group', :aggregate_failures do
get api("/groups/#{group1.id}/descendant_groups", user2)
expect(response).to have_gitlab_http_status(:ok)
@@ -1728,7 +1736,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when using all_available in request' do
- it 'returns public descendants' do
+ it 'returns public descendants', :aggregate_failures do
get api("/groups/#{group1.id}/descendant_groups", user2), params: { all_available: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1752,7 +1760,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group1.add_guest(user2)
end
- it 'returns private descendants' do
+ it 'returns private descendants', :aggregate_failures do
get api("/groups/#{group1.id}/descendant_groups", user2)
expect(response).to have_gitlab_http_status(:ok)
@@ -1763,7 +1771,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when using statistics in request' do
- it 'does not include statistics' do
+ it 'does not include statistics', :aggregate_failures do
get api("/groups/#{group1.id}/descendant_groups", user2), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1778,7 +1786,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
group2.add_guest(user1)
end
- it 'returns descendants' do
+ it 'returns descendants', :aggregate_failures do
get api("/groups/#{group2.id}/descendant_groups", user1)
expect(response).to have_gitlab_http_status(:ok)
@@ -1790,32 +1798,32 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when authenticated as admin' do
- it 'returns private descendants of a public group' do
- get api("/groups/#{group1.id}/descendant_groups", admin)
+ it 'returns private descendants of a public group', :aggregate_failures do
+ get api("/groups/#{group1.id}/descendant_groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
end
- it 'returns descendants of a private group' do
- get api("/groups/#{group2.id}/descendant_groups", admin)
+ it 'returns descendants of a private group', :aggregate_failures do
+ get api("/groups/#{group2.id}/descendant_groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
- it 'does not include statistics by default' do
- get api("/groups/#{group1.id}/descendant_groups", admin)
+ it 'does not include statistics by default', :aggregate_failures do
+ get api("/groups/#{group1.id}/descendant_groups", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
end
- it 'includes statistics if requested' do
- get api("/groups/#{group1.id}/descendant_groups", admin), params: { statistics: true }
+ it 'includes statistics if requested', :aggregate_failures do
+ get api("/groups/#{group1.id}/descendant_groups", admin, admin_mode: true), params: { statistics: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
@@ -1880,7 +1888,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context "when authenticated as user with group permissions" do
- it "creates group" do
+ it "creates group", :aggregate_failures do
group = attributes_for_group_api request_access_enabled: false
post api("/groups", user3), params: group
@@ -1893,7 +1901,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(json_response["visibility"]).to eq(Gitlab::VisibilityLevel.string_level(Gitlab::CurrentSettings.current_application_settings.default_group_visibility))
end
- it "creates a nested group" do
+ it "creates a nested group", :aggregate_failures do
parent = create(:group)
parent.add_owner(user3)
group = attributes_for_group_api parent_id: parent.id
@@ -1926,7 +1934,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
subject { post api("/groups", user3), params: params }
context 'for users who have the ability to create a group with `default_branch_protection`' do
- it 'creates group with the specified branch protection level' do
+ it 'creates group with the specified branch protection level', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:created)
@@ -1935,7 +1943,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'for users who do not have the ability to create a group with `default_branch_protection`' do
- it 'does not create the group with the specified branch protection level' do
+ it 'does not create the group with the specified branch protection level', :aggregate_failures do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user3, :create_group_with_default_branch_protection) { false }
@@ -1947,7 +1955,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it "does not create group, duplicate" do
+ it "does not create group, duplicate", :aggregate_failures do
post api("/groups", user3), params: { name: 'Duplicate Test', path: group2.path }
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2007,13 +2015,13 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context "when authenticated as admin" do
it "removes any existing group" do
- delete api("/groups/#{group2.id}", admin)
+ delete api("/groups/#{group2.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:accepted)
end
it "does not remove a non existing group" do
- delete api("/groups/#{non_existing_record_id}", admin)
+ delete api("/groups/#{non_existing_record_id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -2040,7 +2048,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context "when authenticated as admin" do
it "transfers project to group" do
- post api("/groups/#{group1.id}/projects/#{project.id}", admin)
+ post api("/groups/#{group1.id}/projects/#{project.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:created)
end
@@ -2048,7 +2056,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when using project path in URL' do
context 'with a valid project path' do
it "transfers project to group" do
- post api("/groups/#{group1.id}/projects/#{project_path}", admin)
+ post api("/groups/#{group1.id}/projects/#{project_path}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:created)
end
@@ -2056,7 +2064,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'with a non-existent project path' do
it "does not transfer project to group" do
- post api("/groups/#{group1.id}/projects/nogroup%2Fnoproject", admin)
+ post api("/groups/#{group1.id}/projects/nogroup%2Fnoproject", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -2066,7 +2074,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when using a group path in URL' do
context 'with a valid group path' do
it "transfers project to group" do
- post api("/groups/#{group1.path}/projects/#{project_path}", admin)
+ post api("/groups/#{group1.path}/projects/#{project_path}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:created)
end
@@ -2074,7 +2082,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'with a non-existent group path' do
it "does not transfer project to group" do
- post api("/groups/noexist/projects/#{project_path}", admin)
+ post api("/groups/noexist/projects/#{project_path}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -2183,7 +2191,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
context 'when promoting a subgroup to a root group' do
shared_examples_for 'promotes the subgroup to a root group' do
- it 'returns success' do
+ it 'returns success', :aggregate_failures do
make_request(user)
expect(response).to have_gitlab_http_status(:created)
@@ -2207,7 +2215,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
let(:group) { create(:group) }
let(:params) { { group_id: '' } }
- it 'returns error' do
+ it 'returns error', :aggregate_failures do
make_request(user)
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2258,7 +2266,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
end
- it 'returns error' do
+ it 'returns error', :aggregate_failures do
make_request(user)
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2267,7 +2275,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
end
context 'when the transfer succceds' do
- it 'returns success' do
+ it 'returns success', :aggregate_failures do
make_request(user)
expect(response).to have_gitlab_http_status(:created)
@@ -2289,11 +2297,13 @@ RSpec.describe API::Groups, feature_category: :subgroups do
describe "POST /groups/:id/share" do
shared_examples 'shares group with group' do
- it "shares group with group" do
+ let_it_be(:admin_mode) { false }
+
+ it "shares group with group", :aggregate_failures do
expires_at = 10.days.from_now.to_date
expect do
- post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at }
+ post api("/groups/#{group.id}/share", user, admin_mode: admin_mode), params: { group_id: shared_with_group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at }
end.to change { group.shared_with_group_links.count }.by(1)
expect(response).to have_gitlab_http_status(:created)
@@ -2322,7 +2332,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
expect(response).to have_gitlab_http_status(:not_found)
end
- it "returns a 400 error when wrong params passed" do
+ it "returns a 400 error when wrong params passed", :aggregate_failures do
post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id, group_access: non_existing_record_access_level }
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2375,15 +2385,18 @@ RSpec.describe API::Groups, feature_category: :subgroups do
let(:user) { admin }
let(:group) { create(:group) }
let(:shared_with_group) { create(:group) }
+ let(:admin_mode) { true }
end
end
end
describe 'DELETE /groups/:id/share/:group_id' do
shared_examples 'deletes group share' do
- it 'deletes a group share' do
+ let_it_be(:admin_mode) { false }
+
+ it 'deletes a group share', :aggregate_failures do
expect do
- delete api("/groups/#{shared_group.id}/share/#{shared_with_group.id}", user)
+ delete api("/groups/#{shared_group.id}/share/#{shared_with_group.id}", user, admin_mode: admin_mode)
expect(response).to have_gitlab_http_status(:no_content)
expect(shared_group.shared_with_group_links).to be_empty
@@ -2432,7 +2445,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
create(:group_group_link, shared_group: group1, shared_with_group: group_a)
end
- it 'does not remove group share' do
+ it 'does not remove group share', :aggregate_failures do
expect do
delete api("/groups/#{group1.id}/share/#{group_a.id}", user4)
@@ -2452,6 +2465,7 @@ RSpec.describe API::Groups, feature_category: :subgroups do
let(:user) { admin }
let(:shared_group) { group2 }
let(:shared_with_group) { group_b }
+ let(:admin_mode) { true }
end
end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 81815fdab62..0dca21f752f 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when authenticated' do
- it 'avoids N+1 queries', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/330335' do
+ it 'avoids N+1 queries', :aggregate_failures, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/330335' do
control = ActiveRecord::QueryRecorder.new do
get api(endpoint_path, user)
end
@@ -86,7 +86,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'with merge status recheck projection' do
- it 'checks mergeability asynchronously' do
+ it 'checks mergeability asynchronously', :aggregate_failures do
expect_next_instances_of(check_service_class, (1..2)) do |service|
expect(service).not_to receive(:execute)
expect(service).to receive(:async_execute).and_call_original
@@ -100,7 +100,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'without merge status recheck projection' do
- it 'does not enqueue a merge status recheck' do
+ it 'does not enqueue a merge status recheck', :aggregate_failures do
expect(check_service_class).not_to receive(:new)
get api(endpoint_path, user)
@@ -114,7 +114,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with labels' do
include_context 'with labels'
- it 'returns an array of all merge_requests' do
+ it 'returns an array of all merge_requests', :aggregate_failures do
get api(endpoint_path, user)
expect_paginated_array_response(
@@ -140,7 +140,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'with labels_details' do
- it 'returns labels with details' do
+ it 'returns labels with details', :aggregate_failures do
path = endpoint_path + "?with_labels_details=true"
get api(path, user)
@@ -179,7 +179,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it 'returns an array of all merge_requests using simple mode' do
+ it 'returns an array of all merge_requests using simple mode', :aggregate_failures do
path = endpoint_path + '?view=simple'
get api(path, user)
@@ -200,7 +200,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first).to have_key('web_url')
end
- it 'returns an array of all merge_requests' do
+ it 'returns an array of all merge_requests', :aggregate_failures do
path = endpoint_path + '?state'
get api(path, user)
@@ -215,7 +215,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.last['title']).to eq(merge_request.title)
end
- it 'returns an array of open merge_requests' do
+ it 'returns an array of open merge_requests', :aggregate_failures do
path = endpoint_path + '?state=opened'
get api(path, user)
@@ -224,7 +224,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.last['title']).to eq(merge_request.title)
end
- it 'returns an array of closed merge_requests' do
+ it 'returns an array of closed merge_requests', :aggregate_failures do
path = endpoint_path + '?state=closed'
get api(path, user)
@@ -233,7 +233,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['title']).to eq(merge_request_closed.title)
end
- it 'returns an array of merged merge_requests' do
+ it 'returns an array of merged merge_requests', :aggregate_failures do
path = endpoint_path + '?state=merged'
get api(path, user)
@@ -242,7 +242,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['title']).to eq(merge_request_merged.title)
end
- it 'matches V4 response schema' do
+ it 'matches V4 response schema', :aggregate_failures do
get api(endpoint_path, user)
expect(response).to have_gitlab_http_status(:ok)
@@ -261,7 +261,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect_empty_array_response
end
- it 'returns an array of merge requests in given milestone' do
+ it 'returns an array of merge requests in given milestone', :aggregate_failures do
get api(endpoint_path, user), params: { milestone: '0.9' }
closed_issues = json_response.select { |mr| mr['id'] == merge_request_closed.id }
@@ -269,7 +269,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(closed_issues.first['title']).to eq merge_request_closed.title
end
- it 'returns an array of merge requests matching state in milestone' do
+ it 'returns an array of merge requests matching state in milestone', :aggregate_failures do
get api(endpoint_path, user), params: { milestone: '0.9', state: 'closed' }
expect_paginated_array_response([merge_request_closed.id])
@@ -279,7 +279,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with labels' do
include_context 'with labels'
- it 'returns an array of labeled merge requests' do
+ it 'returns an array of labeled merge requests', :aggregate_failures do
path = endpoint_path + "?labels=#{label.title}"
get api(path, user)
@@ -305,7 +305,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect_empty_array_response
end
- it 'returns an array of labeled merge requests where all labels match' do
+ it 'returns an array of labeled merge requests where all labels match', :aggregate_failures do
path = endpoint_path + "?labels[]=#{label.title}&labels[]=#{label2.title}"
get api(path, user)
@@ -315,7 +315,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['labels']).to eq([label2.title, label.title])
end
- it 'returns an array of merge requests with any label when filtering by any label' do
+ it 'returns an array of merge requests with any label when filtering by any label', :aggregate_failures do
get api(endpoint_path, user), params: { labels: [" #{label.title} ", " #{label2.title} "] }
expect_paginated_array_response([merge_request.id])
@@ -323,7 +323,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['id']).to eq(merge_request.id)
end
- it 'returns an array of merge requests with any label when filtering by any label' do
+ it 'returns an array of merge requests with any label when filtering by any label', :aggregate_failures do
get api(endpoint_path, user), params: { labels: ["#{label.title} , #{label2.title}"] }
expect_paginated_array_response([merge_request.id])
@@ -331,7 +331,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['id']).to eq(merge_request.id)
end
- it 'returns an array of merge requests with any label when filtering by any label' do
+ it 'returns an array of merge requests with any label when filtering by any label', :aggregate_failures do
get api(endpoint_path, user), params: { labels: IssuableFinder::Params::FILTER_ANY }
expect_paginated_array_response([merge_request.id])
@@ -433,7 +433,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response_dates).to eq(response_dates.sort.reverse)
end
- it 'returns an array of merge_requests ordered by created_at' do
+ it 'returns an array of merge_requests ordered by created_at', :aggregate_failures do
path = endpoint_path + '?order_by=created_at&sort=asc'
get api(path, user)
@@ -543,7 +543,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with an id' do
let(:params) { { not: { reviewer_id: user2.id } } }
- it 'returns merge requests that do not have the given reviewer' do
+ it 'returns merge requests that do not have the given reviewer', :aggregate_failures do
get api(endpoint_path, user), params: { not: { reviewer_id: user2.id } }
expect(response).to have_gitlab_http_status(:ok)
@@ -556,7 +556,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with Any' do
let(:params) { { not: { reviewer_id: 'Any' } } }
- it 'returns a 400' do
+ it 'returns a 400', :aggregate_failures do
# Any is not supported for negated filter
get api(endpoint_path, user), params: params
@@ -568,7 +568,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with None' do
let(:params) { { not: { reviewer_id: 'None' } } }
- it 'returns a 400' do
+ it 'returns a 400', :aggregate_failures do
# None is not supported for negated filter
get api(endpoint_path, user), params: params
@@ -581,7 +581,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with reviewer_username' do
let(:params) { { not: { reviewer_username: user2.username } } }
- it 'returns merge requests that do not have the given reviewer' do
+ it 'returns merge requests that do not have the given reviewer', :aggregate_failures do
get api(endpoint_path, user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -594,7 +594,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when both reviewer_id and reviewer_username' do
let(:params) { { not: { reviewer_id: user2.id, reviewer_username: user2.username } } }
- it 'returns a 400' do
+ it 'returns a 400', :aggregate_failures do
get api('/merge_requests', user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@@ -645,7 +645,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
describe 'route shadowing' do
include GrapePathHelpers::NamedRouteMatcher
- it 'does not occur' do
+ it 'does not occur', :aggregate_failures do
path = api_v4_projects_merge_requests_path(id: 1)
expect(path).to eq('/api/v4/projects/1/merge_requests')
@@ -726,7 +726,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
)
end
- it 'does not return unauthorized merge requests' do
+ it 'does not return unauthorized merge requests', :aggregate_failures do
private_project = create(:project, :private)
merge_request3 = create(:merge_request, :simple, source_project: private_project, target_project: private_project, source_branch: 'other-branch')
@@ -777,7 +777,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when both `author_id` and `author_username` are passed' do
- it 'returns a 400' do
+ it 'returns a 400', :aggregate_failures do
get api('/merge_requests', user), params: {
author_id: user.id,
author_username: user2.username,
@@ -855,7 +855,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'with both reviewer_id and reviewer_username' do
let(:params) { super().merge(reviewer_id: user2.id, reviewer_username: user2.username) }
- it 'returns a 400' do
+ it 'returns a 400', :aggregate_failures do
get api('/merge_requests', user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1100,7 +1100,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect_empty_array_response
end
- it 'returns merge_request by "iids" array' do
+ it 'returns merge_request by "iids" array', :aggregate_failures do
get api(endpoint_path, user), params: { iids: [merge_request.iid, merge_request_closed.iid] }
expect_paginated_array_response([merge_request_closed.id, merge_request.id])
@@ -1239,7 +1239,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe "#to_reference" do
- it 'exposes reference path in context of group' do
+ it 'exposes reference path in context of group', :aggregate_failures do
get api("/groups/#{group.id}/merge_requests", user)
expect(json_response.first['references']['short']).to eq("!#{merge_request_merged.iid}")
@@ -1255,7 +1255,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_request_merged.reload
end
- it 'exposes reference path in context of parent group' do
+ it 'exposes reference path in context of parent group', :aggregate_failures do
get api("/groups/#{parent_group.id}/merge_requests")
expect(json_response.first['references']['short']).to eq("!#{merge_request_merged.iid}")
@@ -1296,7 +1296,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
describe "GET /projects/:id/merge_requests/:merge_request_iid" do
let(:merge_request) { create(:merge_request, :simple, author: user, assignees: [user], milestone: milestone, source_project: project, source_branch: 'markdown', title: "Test") }
- it 'matches json schema' do
+ it 'matches json schema', :aggregate_failures do
merge_request = create(:merge_request, :with_test_reports, milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, title: "Test", created_at: base_time)
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
@@ -1304,7 +1304,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response).to match_response_schema('public_api/v4/merge_request')
end
- it 'exposes known attributes' do
+ it 'exposes known attributes', :aggregate_failures do
create(:award_emoji, :downvote, awardable: merge_request)
create(:award_emoji, :upvote, awardable: merge_request)
@@ -1345,7 +1345,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['references']['full']).to eq("#{merge_request.target_project.full_path}!#{merge_request.iid}")
end
- it 'exposes description and title html when render_html is true' do
+ it 'exposes description and title html when render_html is true', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { render_html: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -1368,7 +1368,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_request.update!(author: non_member)
end
- it 'exposes first_contribution as true' do
+ it 'exposes first_contribution as true', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1410,7 +1410,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
'pipeline')
end
- it 'returns correct values' do
+ it 'returns correct values', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(json_response['merged_by']['id']).to eq(merge_request.metrics.merged_by_id)
@@ -1429,7 +1429,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when MR is set to MWPS' do
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds, source_project: project, target_project: project) }
- it 'returns user who set MWPS' do
+ it 'returns user who set MWPS', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1441,7 +1441,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_request.metrics.update!(merged_by: user2)
end
- it 'returns user who actually merged' do
+ it 'returns user who actually merged', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1479,7 +1479,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it 'returns the commits behind the target branch when include_diverged_commits_count is present' do
+ it 'returns the commits behind the target branch when include_diverged_commits_count is present', :aggregate_failures do
allow_any_instance_of(merge_request.class).to receive(:diverged_commits_count).and_return(1)
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { include_diverged_commits_count: true }
@@ -1511,7 +1511,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
)
end
- it "returns merge request" do
+ it "returns merge request", :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request_draft.iid}", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1521,7 +1521,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when a merge request has more than the changes limit' do
- it "returns a string indicating that more changes were made" do
+ it "returns a string indicating that more changes were made", :aggregate_failures do
allow(Commit).to receive(:diff_max_files).and_return(5)
merge_request_overflow = create(:merge_request, :simple,
@@ -1551,7 +1551,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
allow_collaboration: true)
end
- it 'includes the `allow_collaboration` field', :sidekiq_might_not_need_inline do
+ it 'includes the `allow_collaboration` field', :aggregate_failures, :sidekiq_might_not_need_inline do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(json_response['allow_collaboration']).to be_truthy
@@ -1581,7 +1581,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_request.mark_as_unchecked!
end
- it 'checks mergeability asynchronously' do
+ it 'checks mergeability asynchronously', :aggregate_failures do
expect_next_instance_of(MergeRequests::MergeabilityCheckService) do |service|
expect(service).not_to receive(:execute)
expect(service).to receive(:async_execute)
@@ -1605,7 +1605,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe 'GET /projects/:id/merge_requests/:merge_request_iid/reviewers' do
- it 'returns reviewers' do
+ it 'returns reviewers', :aggregate_failures do
reviewer = create(:user)
merge_request.merge_request_reviewers.create!(reviewer: reviewer)
@@ -1645,7 +1645,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
describe 'GET /projects/:id/merge_requests/:merge_request_iid/commits' do
include_context 'with merge requests'
- it 'returns a 200 when merge request is valid' do
+ it 'returns a 200 when merge request is valid', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/commits", user)
commit = merge_request.commits.first
@@ -1677,7 +1677,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let_it_be(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) }
let_it_be(:merge_request_context_commit) { create(:merge_request_context_commit, merge_request: merge_request, message: 'test') }
- it 'returns a 200 when merge request is valid' do
+ it 'returns a 200 when merge request is valid', :aggregate_failures do
context_commit = merge_request.context_commits.first
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/context_commits", user)
@@ -1710,7 +1710,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
shared_examples 'find an existing merge request' do
- it 'returns the change information of the merge_request' do
+ it 'returns the change information of the merge_request', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/changes", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1755,7 +1755,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
it_behaves_like 'find an existing merge request'
it_behaves_like 'accesses diffs via raw_diffs'
- it 'returns the overflow status as false' do
+ it 'returns the overflow status as false', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/changes", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1765,7 +1765,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when using DB-backed diffs' do
it_behaves_like 'find an existing merge request'
- it 'accesses diffs via DB-backed diffs.diffs' do
+ it 'accesses diffs via DB-backed diffs.diffs', :aggregate_failures do
expect_any_instance_of(MergeRequest) do |merge_request|
expect(merge_request).to receive(:diffs).and_call_original
end
@@ -1780,7 +1780,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it 'returns the overflow status as true' do
+ it 'returns the overflow status as true', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/changes", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1828,7 +1828,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it 'returns the diffs of the merge_request' do
+ it 'returns the diffs of the merge_request', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/diffs", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -1836,7 +1836,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when pagination params are present' do
- it 'returns limited diffs' do
+ it 'returns limited diffs', :aggregate_failures do
get(
api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/diffs", user),
params: { page: 1, per_page: 1 }
@@ -1855,7 +1855,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let!(:pipeline) { create(:ci_empty_pipeline, project: project, user: user, ref: merge_request.source_branch, sha: merge_request.diff_head_sha) }
let!(:pipeline2) { create(:ci_empty_pipeline, project: project) }
- it 'returns a paginated array of corresponding pipelines' do
+ it 'returns a paginated array of corresponding pipelines', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/pipelines")
expect_successful_response_with_paginated_array
@@ -1863,7 +1863,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response.first['id']).to eq(pipeline.id)
end
- it 'exposes basic attributes' do
+ it 'exposes basic attributes', :aggregate_failures do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/pipelines")
expect(response).to have_gitlab_http_status(:ok)
@@ -1936,7 +1936,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when authorized' do
- it 'creates and returns the new Pipeline' do
+ it 'creates and returns the new Pipeline', :aggregate_failures do
expect { request }.to change(Ci::Pipeline, :count).by(1)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
@@ -1946,7 +1946,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when unauthorized' do
let(:authenticated_user) { create(:user) }
- it 'responds with a blank 404' do
+ it 'responds with a blank 404', :aggregate_failures do
expect { request }.not_to change(Ci::Pipeline, :count)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -1955,7 +1955,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when the merge request does not exist' do
let(:merge_request_iid) { non_existing_record_id }
- it 'responds with a blank 404' do
+ it 'responds with a blank 404', :aggregate_failures do
expect { request }.not_to change(Ci::Pipeline, :count)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -1964,7 +1964,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
context 'when the .gitlab-ci.yml file is invalid' do
let(:ci_yaml) { 'invalid yaml file' }
- it 'creates a failed pipeline' do
+ it 'creates a failed pipeline', :aggregate_failures do
expect { request }.to change(Ci::Pipeline, :count).by(1)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
@@ -1986,7 +1986,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'creates a new merge request' do
+ it 'creates a new merge request', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user), params: params
expect(response).to have_gitlab_http_status(:created)
@@ -1995,7 +1995,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['assignees'].first['name']).to eq(user2.name)
end
- it 'creates a new merge request when assignee_id is empty' do
+ it 'creates a new merge request when assignee_id is empty', :aggregate_failures do
params[:assignee_id] = ''
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2005,7 +2005,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['assignee']).to be_nil
end
- it 'filters assignee_id of unauthorized user' do
+ it 'filters assignee_id of unauthorized user', :aggregate_failures do
private_project = create(:project, :private, :repository)
another_user = create(:user)
private_project.add_maintainer(user)
@@ -2029,7 +2029,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'creates a new project merge request with no more than one assignee' do
+ it 'creates a new project merge request with no more than one assignee', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user), params: params
expect(response).to have_gitlab_http_status(:created)
@@ -2051,7 +2051,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'creates a new merge request with a reviewer' do
+ it 'creates a new merge request with a reviewer', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user), params: params
expect(response).to have_gitlab_http_status(:created)
@@ -2059,7 +2059,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['reviewers'].first['name']).to eq(user2.name)
end
- it 'creates a new merge request with no reviewer' do
+ it 'creates a new merge request with no reviewer', :aggregate_failures do
params[:reviewer_ids] = []
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2084,7 +2084,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
shared_examples_for 'creates merge request with labels' do
- it 'returns merge_request' do
+ it 'returns merge_request', :aggregate_failures do
params[:labels] = labels
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2109,7 +2109,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let(:labels) { %w(label label2) }
end
- it 'creates merge request with special label names' do
+ it 'creates merge request with special label names', :aggregate_failures do
params[:labels] = 'label, label?, label&foo, ?, &'
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2121,7 +2121,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to include '&'
end
- it 'creates merge request with special label names as array' do
+ it 'creates merge request with special label names as array', :aggregate_failures do
params[:labels] = ['label', 'label?', 'label&foo, ?, &', '1, 2', 3, 4]
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2137,7 +2137,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to include '4'
end
- it 'empty label param does not add any labels' do
+ it 'empty label param does not add any labels', :aggregate_failures do
params[:labels] = ''
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2145,7 +2145,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq([])
end
- it 'empty label param as array does not add any labels, but only explicitly as json' do
+ it 'empty label param as array does not add any labels, but only explicitly as json', :aggregate_failures do
params[:labels] = []
post api("/projects/#{project.id}/merge_requests", user),
params: params.to_json,
@@ -2155,7 +2155,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq([])
end
- it 'empty label param as array, does not add any labels' do
+ it 'empty label param as array, does not add any labels', :aggregate_failures do
params[:labels] = []
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2163,7 +2163,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq([])
end
- it 'array with one empty string element does not add labels' do
+ it 'array with one empty string element does not add labels', :aggregate_failures do
params[:labels] = ['']
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2171,7 +2171,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq([])
end
- it 'array with multiple empty string elements, does not add labels' do
+ it 'array with multiple empty string elements, does not add labels', :aggregate_failures do
params[:labels] = ['', '', '']
post api("/projects/#{project.id}/merge_requests", user), params: params
@@ -2180,7 +2180,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it "returns 422 when source_branch equals target_branch" do
+ it "returns 422 when source_branch equals target_branch", :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user),
params: { title: "Test merge_request", source_branch: "master", target_branch: "master", author: user }
@@ -2188,7 +2188,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['message']).to eq(["You can't use same project/branch for source and target"])
end
- it "returns 400 when source_branch is missing" do
+ it "returns 400 when source_branch is missing", :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user),
params: { title: "Test merge_request", target_branch: "master", author: user }
@@ -2196,7 +2196,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['error']).to eq('source_branch is missing')
end
- it "returns 400 when target_branch is missing" do
+ it "returns 400 when target_branch is missing", :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user),
params: { title: "Test merge_request", source_branch: "markdown", author: user }
@@ -2204,7 +2204,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['error']).to eq('target_branch is missing')
end
- it "returns 400 when title is missing" do
+ it "returns 400 when title is missing", :aggregate_failures do
post api("/projects/#{project.id}/merge_requests", user),
params: { target_branch: 'master', source_branch: 'markdown' }
@@ -2224,7 +2224,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
@mr = MergeRequest.all.last
end
- it 'returns 409 when MR already exists for source/target' do
+ it 'returns 409 when MR already exists for source/target', :aggregate_failures do
expect do
post api("/projects/#{project.id}/merge_requests", user),
params: {
@@ -2273,7 +2273,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
forked_project.add_reporter(user2)
end
- it "returns merge_request" do
+ it "returns merge_request", :aggregate_failures do
post api("/projects/#{forked_project.id}/merge_requests", user2),
params: { title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request' }
expect(response).to have_gitlab_http_status(:created)
@@ -2281,7 +2281,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['description']).to eq('Test description for Test merge_request')
end
- it "does not return 422 when source_branch equals target_branch" do
+ it "does not return 422 when source_branch equals target_branch", :aggregate_failures do
expect(project.id).not_to eq(forked_project.id)
expect(forked_project.forked?).to be_truthy
expect(forked_project.forked_from_project).to eq(project)
@@ -2324,7 +2324,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response).to have_gitlab_http_status(:bad_request)
end
- it 'allows setting `allow_collaboration`', :sidekiq_might_not_need_inline do
+ it 'allows setting `allow_collaboration`', :aggregate_failures, :sidekiq_might_not_need_inline do
post api("/projects/#{forked_project.id}/merge_requests", user2),
params: { title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master", author: user2, target_project_id: project.id, allow_collaboration: true }
expect(response).to have_gitlab_http_status(:created)
@@ -2429,7 +2429,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'sets the assignees' do
+ it 'sets the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2462,7 +2462,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'sets the assignees' do
+ it 'sets the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2479,7 +2479,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'clears the assignees' do
+ it 'clears the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2500,7 +2500,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'clears the assignees' do
+ it 'clears the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2515,7 +2515,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'clears the assignees' do
+ it 'clears the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2530,7 +2530,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'clears the assignees' do
+ it 'clears the assignees', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2546,7 +2546,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
}
end
- it 'adds a reviewer to the existing merge request' do
+ it 'adds a reviewer to the existing merge request', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
expect(response).to have_gitlab_http_status(:ok)
@@ -2554,7 +2554,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['reviewers'].first['name']).to eq(user2.name)
end
- it 'removes a reviewer from the existing merge request' do
+ it 'removes a reviewer from the existing merge request', :aggregate_failures do
merge_request.reviewers = [user2]
params[:reviewer_ids] = []
@@ -2591,7 +2591,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe 'when authenticated' do
- it 'creates and returns the new context commit' do
+ it 'creates and returns the new context commit', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests/#{merge_request_iid}/context_commits", authenticated_user), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to be_an Array
@@ -2609,14 +2609,14 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
create(:merge_request_context_commit, merge_request: merge_request, sha: commit.id)
end
- it 'returns 400 when the context commit is already created' do
+ it 'returns 400 when the context commit is already created', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests/#{merge_request_iid}/context_commits", authenticated_user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq("Context commits: [\"#{commit.id}\"] are already created")
end
end
- it 'returns 400 when one or more shas are invalid' do
+ it 'returns 400 when one or more shas are invalid', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests/#{merge_request_iid}/context_commits", authenticated_user), params: params_invalid_shas
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq('One or more context commits\' sha is not valid.')
@@ -2724,7 +2724,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response).to have_gitlab_http_status(:no_content)
end
- it "returns 400 when invalid commit sha is passed" do
+ it "returns 400 when invalid commit sha is passed", :aggregate_failures do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/context_commits", authenticated_user), params: params_invalid_shas
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2782,7 +2782,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when the merge request fails to merge' do
- it 'returns 422' do
+ it 'returns 422', :aggregate_failures do
expect_next_instance_of(::MergeRequests::MergeService) do |service|
expect(service).to receive(:execute)
end
@@ -2795,7 +2795,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it "returns 422 if branch can't be merged" do
+ it "returns 422 if branch can't be merged", :aggregate_failures do
allow_next_found_instance_of(MergeRequest) do |merge_request|
allow(merge_request).to receive(:can_be_merged?).and_return(false)
end
@@ -2806,21 +2806,21 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['message']).to eq('Branch cannot be merged')
end
- it "returns 405 if merge_request is not open" do
+ it "returns 405 if merge_request is not open", :aggregate_failures do
merge_request.close
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
expect(response).to have_gitlab_http_status(:method_not_allowed)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
- it "returns 405 if merge_request is a draft" do
+ it "returns 405 if merge_request is a draft", :aggregate_failures do
merge_request.update_attribute(:title, "Draft: #{merge_request.title}")
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
expect(response).to have_gitlab_http_status(:method_not_allowed)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
- it 'returns 405 if the build failed for a merge request that requires success' do
+ it 'returns 405 if the build failed for a merge request that requires success', :aggregate_failures do
project.update!(only_allow_merge_if_pipeline_succeeds: true)
create(:ci_pipeline,
@@ -2834,7 +2834,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['message']).to eq('405 Method Not Allowed')
end
- it "returns 401 if user has no permissions to merge" do
+ it "returns 401 if user has no permissions to merge", :aggregate_failures do
user2 = create(:user)
project.add_reporter(user2)
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user2)
@@ -2842,7 +2842,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['message']).to eq('401 Unauthorized')
end
- it "returns 409 if the SHA parameter doesn't match" do
+ it "returns 409 if the SHA parameter doesn't match", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { sha: merge_request.diff_head_sha.reverse }
expect(response).to have_gitlab_http_status(:conflict)
@@ -2863,7 +2863,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response).to have_gitlab_http_status(:ok)
end
- it 'does not merge if merge_when_pipeline_succeeds is passed and the pipeline has failed' do
+ it 'does not merge if merge_when_pipeline_succeeds is passed and the pipeline has failed', :aggregate_failures do
create(:ci_pipeline,
:failed,
sha: merge_request.diff_head_sha,
@@ -2875,7 +2875,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(merge_request.reload.state).to eq('opened')
end
- it 'merges if the head pipeline already succeeded and `merge_when_pipeline_succeeds` is passed' do
+ it 'merges if the head pipeline already succeeded and `merge_when_pipeline_succeeds` is passed', :aggregate_failures do
create(:ci_pipeline, :success, sha: merge_request.diff_head_sha, merge_requests_as_head_pipeline: [merge_request])
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: { merge_when_pipeline_succeeds: true }
@@ -2884,7 +2884,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['state']).to eq('merged')
end
- it "enables merge when pipeline succeeds if the pipeline is active" do
+ it "enables merge when pipeline succeeds if the pipeline is active", :aggregate_failures do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, actual_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
@@ -2895,7 +2895,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
- it "enables merge when pipeline succeeds if the pipeline is active and only_allow_merge_if_pipeline_succeeds is true" do
+ it "enables merge when pipeline succeeds if the pipeline is active and only_allow_merge_if_pipeline_succeeds is true", :aggregate_failures do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, actual_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true)
@@ -2946,7 +2946,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let(:source_repository) { merge_request.source_project.repository }
let(:source_branch) { merge_request.source_branch }
- it 'removes the source branch when set' do
+ it 'removes the source branch when set', :aggregate_failures do
put(
api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user),
params: { should_remove_source_branch: true }
@@ -2966,7 +2966,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_request.update!(merge_params: { 'force_remove_source_branch' => true })
end
- it 'removes the source branch' do
+ it 'removes the source branch', :aggregate_failures do
put(
api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
)
@@ -2976,7 +2976,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(merge_request.reload.should_remove_source_branch?).to be nil
end
- it 'does not remove the source branch' do
+ it 'does not remove the source branch', :aggregate_failures do
put(
api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user),
params: { should_remove_source_branch: false }
@@ -2995,7 +2995,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
project.update!(merge_requests_ff_only_enabled: true)
end
- it "records the squash commit SHA and returns it in the response" do
+ it "records the squash commit SHA and returns it in the response", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -3015,14 +3015,14 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
"/projects/#{project.id}/merge_requests/#{merge_request_iid}/merge_ref"
end
- it 'returns the generated ID from the merge service in case of success' do
+ it 'returns the generated ID from the merge service in case of success', :aggregate_failures do
get api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commit_id']).to eq(merge_request.merge_ref_head.sha)
end
- context 'when merge-ref is not synced with merge status' do
+ context 'when merge-ref is not synced with merge status', :aggregate_failures do
let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, source_branch: 'markdown', merge_status: 'cannot_be_merged') }
it 'returns 200 if MR can be merged' do
@@ -3032,7 +3032,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['commit_id']).to eq(merge_request.merge_ref_head.sha)
end
- it 'returns 400 if MR cannot be merged' do
+ it 'returns 400 if MR cannot be merged', :aggregate_failures do
expect_next_instance_of(MergeRequests::MergeToRefService) do |merge_request|
expect(merge_request).to receive(:execute) { { status: :failed } }
end
@@ -3048,7 +3048,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let(:project) { create(:project, :private) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- it 'returns 404' do
+ it 'returns 404', :aggregate_failures do
project.add_guest(user)
get api(url, user)
@@ -3081,7 +3081,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
describe "PUT /projects/:id/merge_requests/:merge_request_iid" do
context 'updates force_remove_source_branch properly' do
- it 'sets to false' do
+ it 'sets to false', :aggregate_failures do
merge_request.update!(merge_params: { 'force_remove_source_branch' => true })
expect(merge_request.force_remove_source_branch?).to be_truthy
@@ -3093,7 +3093,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['force_remove_source_branch']).to be_falsey
end
- it 'sets to true' do
+ it 'sets to true', :aggregate_failures do
merge_request.update!(merge_params: { 'force_remove_source_branch' => false })
expect(merge_request.force_remove_source_branch?).to be false
@@ -3119,7 +3119,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
merge_params: { 'force_remove_source_branch' => false })
end
- it 'is true for an authorized user' do
+ it 'is true for an authorized user', :aggregate_failures do
put api("/projects/#{target_project.id}/merge_requests/#{merge_request.iid}", fork_owner), params: { state_event: 'close', remove_source_branch: true }
expect(response).to have_gitlab_http_status(:ok)
@@ -3127,7 +3127,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['force_remove_source_branch']).to be true
end
- it 'is false for an unauthorized user' do
+ it 'is false for an unauthorized user', :aggregate_failures do
expect do
put api("/projects/#{target_project.id}/merge_requests/#{merge_request.iid}", target_project.first_owner), params: { state_event: 'close', remove_source_branch: true }
end.not_to change { merge_request.reload.merge_params }
@@ -3140,7 +3140,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context "to close a MR" do
- it "returns merge_request" do
+ it "returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: "close" }
expect(response).to have_gitlab_http_status(:ok)
@@ -3148,32 +3148,32 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it "updates title and returns merge_request" do
+ it "updates title and returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { title: "New title" }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['title']).to eq('New title')
end
- it "updates description and returns merge_request" do
+ it "updates description and returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { description: "New description" }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['description']).to eq('New description')
end
- it "updates milestone_id and returns merge_request" do
+ it "updates milestone_id and returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { milestone_id: milestone.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['milestone']['id']).to eq(milestone.id)
end
- it "updates squash and returns merge_request" do
+ it "updates squash and returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { squash: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['squash']).to be_truthy
end
- it "updates target_branch and returns merge_request" do
+ it "updates target_branch and returns merge_request", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { target_branch: "wiki" }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['target_branch']).to eq('wiki')
@@ -3193,7 +3193,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
shared_examples "update of allow_collaboration and allow_maintainer_to_push" do |request_value, expected_value|
%w[allow_collaboration allow_maintainer_to_push].each do |attr|
- it "attempts to update #{attr} to #{request_value} and returns #{expected_value} for `allow_collaboration`" do
+ it "attempts to update #{attr} to #{request_value} and returns #{expected_value} for `allow_collaboration`", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user2), params: { attr => request_value }
expect(response).to have_gitlab_http_status(:ok)
@@ -3214,14 +3214,14 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it "returns merge_request that removes the source branch" do
+ it "returns merge_request that removes the source branch", :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { remove_source_branch: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['force_remove_source_branch']).to be_truthy
end
- it 'filters assignee_id of unauthorized user' do
+ it 'filters assignee_id of unauthorized user', :aggregate_failures do
private_project = create(:project, :private, :repository)
mr = create(:merge_request, source_project: private_project, target_project: private_project)
another_user = create(:user)
@@ -3235,7 +3235,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when updating labels' do
- it 'allows special label names' do
+ it 'allows special label names', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3250,7 +3250,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to include '&'
end
- it 'also accepts labels as an array' do
+ it 'also accepts labels as an array', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3269,7 +3269,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to include '4'
end
- it 'empty label param removes labels' do
+ it 'empty label param removes labels', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3280,7 +3280,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq []
end
- it 'label param as empty array, but only explicitly as json, removes labels' do
+ it 'label param as empty array, but only explicitly as json, removes labels', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3292,7 +3292,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq []
end
- it 'empty label as array, removes labels' do
+ it 'empty label as array, removes labels', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3303,7 +3303,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq []
end
- it 'array with one empty string element removes labels' do
+ it 'array with one empty string element removes labels', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3314,7 +3314,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(json_response['labels']).to eq []
end
- it 'array with multiple empty string elements, removes labels' do
+ it 'array with multiple empty string elements, removes labels', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user),
params: {
title: 'new issue',
@@ -3331,21 +3331,21 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
let(:api_base) { api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user) }
- it 'when adding labels, keeps existing labels and adds new' do
+ it 'when adding labels, keeps existing labels and adds new', :aggregate_failures do
put api_base, params: { add_labels: '1, 2' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to contain_exactly(label.title, label2.title, '1', '2')
end
- it 'when removing labels, only removes those specified' do
+ it 'when removing labels, only removes those specified', :aggregate_failures do
put api_base, params: { remove_labels: label.title.to_s }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to eq([label2.title])
end
- it 'when removing all labels, keeps no labels' do
+ it 'when removing all labels, keeps no labels', :aggregate_failures do
put api_base, params: { remove_labels: "#{label.title}, #{label2.title}" }
expect(response).to have_gitlab_http_status(:ok)
@@ -3353,7 +3353,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
end
- it 'does not update state when title is empty' do
+ it 'does not update state when title is empty', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: 'close', title: nil }
merge_request.reload
@@ -3361,7 +3361,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(merge_request.state).to eq('opened')
end
- it 'does not update state when target_branch is empty' do
+ it 'does not update state when target_branch is empty', :aggregate_failures do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { state_event: 'close', target_branch: nil }
merge_request.reload
@@ -3383,7 +3383,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe 'GET :id/merge_requests/:merge_request_iid/closes_issues' do
- it 'returns the issue that will be closed on merge' do
+ it 'returns the issue that will be closed on merge', :aggregate_failures do
issue = create(:issue, project: project)
mr = merge_request.tap do |mr|
mr.update_attribute(:description, "Closes #{issue.to_reference(mr.project)}")
@@ -3403,7 +3403,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect_empty_array_response
end
- it 'handles external issues' do
+ it 'handles external issues', :aggregate_failures do
jira_project = create(:project, :with_jira_integration, :public, :repository, name: 'JIR_EXT1')
ext_issue = ExternalIssue.new("#{jira_project.name}-123", jira_project)
issue = create(:issue, project: jira_project)
@@ -3448,8 +3448,8 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe 'POST :id/merge_requests/:merge_request_iid/subscribe' do
- it 'subscribes to a merge request' do
- post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", admin)
+ it 'subscribes to a merge request', :aggregate_failures do
+ post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:created)
expect(json_response['subscribed']).to eq(true)
@@ -3484,7 +3484,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
describe 'POST :id/merge_requests/:merge_request_iid/unsubscribe' do
- it 'unsubscribes from a merge request' do
+ it 'unsubscribes from a merge request', :aggregate_failures do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", user)
expect(response).to have_gitlab_http_status(:created)
@@ -3492,7 +3492,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
it 'returns 304 if not subscribed' do
- post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", admin)
+ post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:not_modified)
end
@@ -3545,7 +3545,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
describe 'PUT :id/merge_requests/:merge_request_iid/rebase' do
context 'when rebase can be performed' do
- it 'enqueues a rebase of the merge request against the target branch' do
+ it 'enqueues a rebase of the merge request against the target branch', :aggregate_failures do
Sidekiq::Testing.fake! do
expect do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user)
@@ -3558,7 +3558,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
end
context 'when skip_ci parameter is set' do
- it 'enqueues a rebase of the merge request with skip_ci flag set' do
+ it 'enqueues a rebase of the merge request with skip_ci flag set', :aggregate_failures do
with_status = RebaseWorker.with_status
expect(RebaseWorker).to receive(:with_status).and_return(with_status)
@@ -3609,7 +3609,7 @@ RSpec.describe API::MergeRequests, feature_category: :source_code_management do
expect(response).to have_gitlab_http_status(:conflict)
end
- it "returns 409 if rebase can't lock the row" do
+ it "returns 409 if rebase can't lock the row", :aggregate_failures do
allow_any_instance_of(MergeRequest).to receive(:with_lock).and_raise(ActiveRecord::LockWaitTimeout)
expect(RebaseWorker).not_to receive(:perform_async)
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index c0276e02eb7..d535629ea0d 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -70,7 +70,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
describe "GET /projects/:id/noteable/:noteable_id/notes" do
context "current user cannot view the notes" do
- it "returns an empty array" do
+ it "returns an empty array", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", user)
expect(response).to have_gitlab_http_status(:ok)
@@ -93,7 +93,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
end
context "current user can view the note" do
- it "returns a non-empty array" do
+ it "returns a non-empty array", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", private_user)
expect(response).to have_gitlab_http_status(:ok)
@@ -114,7 +114,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
let(:test_url) { "/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes" }
shared_examples 'a notes request' do
- it 'is a note array response' do
+ it 'is a note array response', :aggregate_failures do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -164,7 +164,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
it_behaves_like 'a notes request'
- it "properly filters the returned notables" do
+ it "properly filters the returned notables", :aggregate_failures do
expect(json_response.count).to eq(count)
expect(json_response.first["system"]).to be system_notable
end
@@ -195,7 +195,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
end
context "current user can view the note" do
- it "returns an issue note by id" do
+ it "returns an issue note by id", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes/#{cross_reference_note.id}", private_user)
expect(response).to have_gitlab_http_status(:ok)
diff --git a/spec/requests/api/personal_access_tokens/self_information_spec.rb b/spec/requests/api/personal_access_tokens/self_information_spec.rb
index 2a7af350054..3cfaaaf7d3f 100644
--- a/spec/requests/api/personal_access_tokens/self_information_spec.rb
+++ b/spec/requests/api/personal_access_tokens/self_information_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe API::PersonalAccessTokens::SelfInformation, feature_category: :sy
subject(:delete_token) { delete api(path, personal_access_token: token) }
shared_examples 'revoking token succeeds' do
- it 'revokes token' do
+ it 'revokes token', :aggregate_failures do
delete_token
expect(response).to have_gitlab_http_status(:no_content)
@@ -72,7 +72,7 @@ RSpec.describe API::PersonalAccessTokens::SelfInformation, feature_category: :sy
context "with a '#{scope}' scoped token" do
let(:token) { create(:personal_access_token, scopes: [scope], user: current_user) }
- it 'shows token info' do
+ it 'shows token info', :aggregate_failures do
get api(path, personal_access_token: token)
expect(response).to have_gitlab_http_status(:ok)
diff --git a/spec/requests/api/personal_access_tokens_spec.rb b/spec/requests/api/personal_access_tokens_spec.rb
index cca94c7a012..308fdbce30f 100644
--- a/spec/requests/api/personal_access_tokens_spec.rb
+++ b/spec/requests/api/personal_access_tokens_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
shared_examples 'response as expected' do |params|
subject { get api(path, personal_access_token: current_users_token), params: params }
- it "status, count and result as expected" do
+ it "status, count and result as expected", :aggregate_failures do
subject
case status
@@ -32,9 +32,9 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'logged in as an Administrator' do
let_it_be(:current_user) { create(:admin) }
- let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
+ let_it_be(:current_users_token) { create(:personal_access_token, :admin_mode, user: current_user) }
- it 'returns all PATs by default' do
+ it 'returns all PATs by default', :aggregate_failures do
get api(path, current_user)
expect(response).to have_gitlab_http_status(:ok)
@@ -45,8 +45,8 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:token) { create(:personal_access_token) }
let_it_be(:token_impersonated) { create(:personal_access_token, impersonation: true, user: token.user) }
- it 'returns only PATs belonging to that user' do
- get api(path, current_user), params: { user_id: token.user.id }
+ it 'returns only PATs belonging to that user', :aggregate_failures do
+ get api(path, current_user, admin_mode: true), params: { user_id: token.user.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.count).to eq(2)
@@ -243,7 +243,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:current_user) { create(:user) }
let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
- it 'returns all PATs belonging to the signed-in user' do
+ it 'returns all PATs belonging to the signed-in user', :aggregate_failures do
get api(path, personal_access_token: current_users_token)
expect(response).to have_gitlab_http_status(:ok)
@@ -255,7 +255,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'filtered with user_id parameter' do
let_it_be(:user) { create(:user) }
- it 'returns PATs belonging to the specific user' do
+ it 'returns PATs belonging to the specific user', :aggregate_failures do
get api(path, current_user, personal_access_token: current_users_token), params: { user_id: current_user.id }
expect(response).to have_gitlab_http_status(:ok)
@@ -393,14 +393,14 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:admin_token) { create(:personal_access_token, user: admin_user) }
let_it_be(:admin_path) { "/personal_access_tokens/#{admin_token.id}" }
- it 'returns admins own PAT by id' do
+ it 'returns admins own PAT by id', :aggregate_failures do
get api(admin_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq(admin_token.id)
end
- it 'returns a different users PAT by id' do
+ it 'returns a different users PAT by id', :aggregate_failures do
get api(user_token_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
@@ -417,7 +417,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'when current_user is not an administrator' do
let_it_be(:other_users_path) { "/personal_access_tokens/#{token1.id}" }
- it 'returns users own PAT by id' do
+ it 'returns users own PAT by id', :aggregate_failures do
get api(user_token_path, current_user)
expect(response).to have_gitlab_http_status(:ok)
@@ -458,7 +458,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
create(:personal_access_token, scopes: ['read_repository'], user: admin_user)
end
- it 'revokes a different users token' do
+ it 'revokes a different users token', :aggregate_failures do
delete api(path, admin_user)
expect(response).to have_gitlab_http_status(:no_content)
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index c3f99872cef..a36f4f1d2f5 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
- it 'returns releases ordered by released_at' do
+ it 'returns releases ordered by released_at', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(2)
@@ -113,7 +113,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to match_response_schema('public_api/v4/releases')
end
- it 'returns rendered helper paths' do
+ it 'returns rendered helper paths', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.first['commit_path']).to eq("/#{release_2.project.full_path}/-/commit/#{release_2.commit.id}")
@@ -132,7 +132,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
end
- it 'returns an upcoming_release status for a future release' do
+ it 'returns an upcoming_release status for a future release', :aggregate_failures do
tomorrow = Time.now.utc + 1.day
create(:release, project: project, tag: 'v0.1', author: maintainer, released_at: tomorrow)
@@ -142,7 +142,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response.first['upcoming_release']).to eq(true)
end
- it 'returns an upcoming_release status for a past release' do
+ it 'returns an upcoming_release status for a past release', :aggregate_failures do
yesterday = Time.now.utc - 1.day
create(:release, project: project, tag: 'v0.1', author: maintainer, released_at: yesterday)
@@ -152,7 +152,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response.first['upcoming_release']).to eq(false)
end
- it 'avoids N+1 queries', :use_sql_query_cache do
+ it 'avoids N+1 queries', :aggregate_failures, :use_sql_query_cache do
create(:release, :with_evidence, project: project, tag: 'v0.1', author: maintainer)
create(:release_link, release: project.releases.first)
@@ -211,7 +211,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag does not exist in git repository' do
let!(:release) { create(:release, project: project, tag: 'v1.1.5') }
- it 'returns the tag' do
+ it 'returns the tag', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(1)
@@ -223,7 +223,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag contains a slash' do
let!(:release) { create(:release, project: project, tag: 'debian/2.4.0-1', description: "debian/2.4.0-1") }
- it 'returns 200 HTTP status' do
+ it 'returns 200 HTTP status', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to have_gitlab_http_status(:ok)
@@ -246,7 +246,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
- it "does not expose tag, commit, source code or helper paths" do
+ it "does not expose tag, commit, source code or helper paths", :aggregate_failures do
get api("/projects/#{project.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/release/releases_for_guest')
@@ -264,7 +264,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
- it "exposes tag, commit, source code and helper paths" do
+ it "exposes tag, commit, source code and helper paths", :aggregate_failures do
get api("/projects/#{project.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/releases')
@@ -296,7 +296,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when releases are public and request user is absent' do
let(:project) { create(:project, :repository, :public) }
- it 'returns the releases' do
+ it 'returns the releases', :aggregate_failures do
create(:release, project: project, tag: 'v0.1')
get api("/projects/#{project.id}/releases")
@@ -333,7 +333,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
- it 'returns a release entry' do
+ it 'returns a release entry', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['tag_name']).to eq(release.tag)
@@ -351,7 +351,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to match_response_schema('public_api/v4/release')
end
- it 'contains source information as assets' do
+ it 'contains source information as assets', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['assets']['sources'].map { |h| h['format'] })
@@ -413,7 +413,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:url) { 'https://my-external-hosting.example.com/scrambled-url/app.zip' }
- it 'contains link information as assets' do
+ it 'contains link information as assets', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['assets']['links'].count).to eq(1)
@@ -480,14 +480,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when specified tag is not found in the project' do
- it 'returns 404 for maintater' do
+ it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/non_exist_tag", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not Found')
end
- it 'returns project not found for no user' do
+ it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/non_exist_tag", nil)
expect(response).to have_gitlab_http_status(:not_found)
@@ -538,7 +538,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response['milestones'].first['title']).to eq(milestone.title)
end
- it 'returns issue stats for milestone' do
+ it 'returns issue stats for milestone', :aggregate_failures do
create_list(:issue, 2, milestone: milestone, project: project)
create_list(:issue, 3, :closed, milestone: milestone, project: project)
@@ -580,14 +580,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:url) { 'https://google.com/-/jobs/140463678/artifacts/download' }
context 'with an invalid release tag' do
- it 'returns 404 for maintater' do
+ it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.2/downloads#{filepath}", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not Found')
end
- it 'returns project not found for no user' do
+ it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.2/downloads#{filepath}", nil)
expect(response).to have_gitlab_http_status(:not_found)
@@ -648,14 +648,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when filepath does not exists' do
- it 'returns 404 for maintater' do
+ it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1/downloads/bin/not_existing.exe", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')
end
- it 'returns project not found for no user' do
+ it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1/downloads/bin/not_existing.exe", nil)
expect(response).to have_gitlab_http_status(:not_found)
@@ -728,7 +728,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
released_at: 2.days.ago)
end
- it 'redirects to the latest release tag' do
+ it 'redirects to the latest release tag', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer)
uri = URI(response.header["Location"])
@@ -737,7 +737,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(uri.path).to eq("/api/v4/projects/#{project.id}/releases/#{release_b.tag}")
end
- it 'redirects to the latest release tag when using JOB-TOKEN auth' do
+ it 'redirects to the latest release tag when using JOB-TOKEN auth', :aggregate_failures do
job = create(:ci_build, :running, project: project, user: maintainer)
get api("/projects/#{project.id}/releases/permalink/latest"), params: { job_token: job.token }
@@ -748,7 +748,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(uri.path).to eq("/api/v4/projects/#{project.id}/releases/#{release_b.tag}")
end
- context 'when there are query parameters present' do
+ context 'when there are query parameters present', :aggregate_failures do
it 'includes the query params on the redirection' do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer), params: { include_html_description: true, other_param: "aaa" }
@@ -763,7 +763,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
})
end
- it 'discards the `order_by` query param' do
+ it 'discards the `order_by` query param', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer), params: { order_by: 'something', other_param: "aaa" }
uri = URI(response.header["Location"])
@@ -781,7 +781,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when downloading a release asset' do
- it 'redirects to the right endpoint keeping the suffix_path' do
+ it 'redirects to the right endpoint keeping the suffix_path', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest/downloads/bin/example.exe", maintainer)
uri = URI(response.header["Location"])
@@ -830,7 +830,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:created)
end
- it 'creates a new release' do
+ it 'creates a new release', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@@ -848,7 +848,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
end
- it 'creates a new release without description' do
+ it 'creates a new release without description', :aggregate_failures do
params = {
name: 'New release without description',
tag_name: 'v0.1',
@@ -926,7 +926,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
params[:direct_asset_path] = params.delete(:filepath)
end
- it 'creates a new release successfully' do
+ it 'creates a new release successfully', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@@ -1010,7 +1010,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:created)
end
- it 'creates an asset with specified parameters' do
+ it 'creates an asset with specified parameters', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(json_response['assets']['links'].count).to eq(1)
@@ -1038,7 +1038,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
})
end
- it 'creates two assets with specified parameters' do
+ it 'creates two assets with specified parameters', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(json_response['assets']['links'].count).to eq(2)
@@ -1099,7 +1099,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when a valid token is provided' do
- it 'creates the release for a running job' do
+ it 'creates the release for a running job', :aggregate_failures do
job.update!(status: :running, project: project)
post api("/projects/#{project.id}/releases"), params: params.merge(job_token: job.token)
@@ -1139,7 +1139,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
.to eq(project.repository.commit('master').id)
end
- it 'creates a new release' do
+ it 'creates a new release', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@@ -1155,7 +1155,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag name is HEAD' do
let(:tag_name) { 'HEAD' }
- it 'returns a 400 error as failure on tag creation' do
+ it 'returns a 400 error as failure on tag creation', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1166,7 +1166,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag name is empty' do
let(:tag_name) { '' }
- it 'returns a 400 error as failure on tag creation' do
+ it 'returns a 400 error as failure on tag creation', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1216,7 +1216,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with a project milestone' do
shared_examples 'adds milestone' do
- it 'adds the milestone' do
+ it 'adds the milestone', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(returned_milestones).to match_array(['v1.0'])
end
@@ -1239,7 +1239,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:milestone2) { create(:milestone, project: project, title: 'm2') }
let(:milestone_params) { { milestones: [milestone.title, milestone2.title] } }
- it 'adds all milestones' do
+ it 'adds all milestones', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(returned_milestones).to match_array(['v1.0', 'm2'])
end
@@ -1248,7 +1248,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with an empty milestone' do
let(:milestone_params) { { milestones: [] } }
- it 'removes all milestones' do
+ it 'removes all milestones', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['milestones']).to be_nil
end
@@ -1257,7 +1257,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with a non-existant milestone' do
let(:milestone_params) { { milestones: ['xyz'] } }
- it 'returns a 400 error as milestone not found' do
+ it 'returns a 400 error as milestone not found', :aggregate_failures do
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq("Milestone(s) not found: xyz")
end
@@ -1267,7 +1267,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:milestone) { create(:milestone, title: 'v1.0') }
let(:milestone_params) { { milestones: [milestone.title] } }
- it 'returns a 400 error as milestone not found' do
+ it 'returns a 400 error as milestone not found', :aggregate_failures do
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq("Milestone(s) not found: v1.0")
end
@@ -1311,7 +1311,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(project.releases.last.description).to eq('Best release ever!')
end
- it 'does not change other attributes' do
+ it 'does not change other attributes', :aggregate_failures do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(project.releases.last.tag).to eq('v0.1')
@@ -1427,7 +1427,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
shared_examples 'updates milestone' do
- it 'updates the milestone' do
+ it 'updates the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1461,7 +1461,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'an empty milestone' do
let(:params) { { milestones: [] } }
- it 'removes the milestone' do
+ it 'removes the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1472,7 +1472,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'without milestones parameter' do
let(:params) { { name: 'some new name' } }
- it 'does not change the milestone' do
+ it 'does not change the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1485,7 +1485,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let!(:milestone2) { create(:milestone, project: project, title: 'milestone2') }
let(:params) { { milestones: [milestone.title, milestone2.title] } }
- it 'adds the new milestone' do
+ it 'adds the new milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1498,7 +1498,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let!(:milestone3) { create(:milestone, project: project, title: 'milestone3') }
shared_examples 'update milestones' do
- it 'replaces the milestones' do
+ it 'replaces the milestones', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@@ -1665,8 +1665,8 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let_it_be(:release2) { create(:release, project: project2) }
let_it_be(:release3) { create(:release, project: project3) }
- context 'when authenticated as owner' do
- it 'gets releases from all projects in the group' do
+ context 'when authenticated as owner', :enable_admin_mode do
+ it 'gets releases from all projects in the group', :aggregate_failures do
get api("/groups/#{group1.id}/releases", admin)
expect(response).to have_gitlab_http_status(:ok)
@@ -1700,7 +1700,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
group1.add_guest(guest)
end
- it "does not expose tag, commit, source code or helper paths" do
+ it "does not expose tag, commit, source code or helper paths", :aggregate_failures do
get api("/groups/#{group1.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/release/releases_for_guest')
@@ -1715,9 +1715,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with subgroups' do
let(:group) { create(:group) }
- it 'include_subgroups avoids N+1 queries' do
+ subject { get api("/groups/#{group.id}/releases", admin, admin_mode: true), params: query_params.merge({ include_subgroups: true }) }
+
+ it 'include_subgroups avoids N+1 queries', :aggregate_failures, :use_sql_query_cache do
+ subject
+ expect(response).to have_gitlab_http_status(:ok)
+
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
- get api("/groups/#{group.id}/releases", admin), params: query_params.merge({ include_subgroups: true })
+ subject
end.count
subgroups = create_list(:group, 10, parent: group1)
@@ -1725,7 +1730,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
create_list(:release, 10, project: projects[0], author: admin)
expect do
- get api("/groups/#{group.id}/releases", admin), params: query_params.merge({ include_subgroups: true })
+ subject
end.not_to exceed_all_query_limit(control_count)
end
end
diff --git a/spec/requests/api/sidekiq_metrics_spec.rb b/spec/requests/api/sidekiq_metrics_spec.rb
index 32c4c323923..d24fbb50306 100644
--- a/spec/requests/api/sidekiq_metrics_spec.rb
+++ b/spec/requests/api/sidekiq_metrics_spec.rb
@@ -6,8 +6,8 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
let(:admin) { create(:user, :admin) }
describe 'GET sidekiq/*' do
- it 'defines the `queue_metrics` endpoint' do
- get api('/sidekiq/queue_metrics', admin)
+ it 'defines the `queue_metrics` endpoint', :aggregate_failures do
+ get api('/sidekiq/queue_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to match a_hash_including(
@@ -24,15 +24,15 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
)
end
- it 'defines the `process_metrics` endpoint' do
- get api('/sidekiq/process_metrics', admin)
+ it 'defines the `process_metrics` endpoint', :aggregate_failures do
+ get api('/sidekiq/process_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['processes']).to be_an Array
end
- it 'defines the `job_stats` endpoint' do
- get api('/sidekiq/job_stats', admin)
+ it 'defines the `job_stats` endpoint', :aggregate_failures do
+ get api('/sidekiq/job_stats', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
@@ -42,8 +42,8 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
expect(json_response['jobs'].values).to all(be_an(Integer))
end
- it 'defines the `compound_metrics` endpoint' do
- get api('/sidekiq/compound_metrics', admin)
+ it 'defines the `compound_metrics` endpoint', :aggregate_failures do
+ get api('/sidekiq/compound_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index bde160b03cd..f2a16ae3452 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -360,21 +360,13 @@ RSpec.configure do |config|
./spec/requests/api/broadcast_messages_spec.rb
./spec/requests/api/deploy_keys_spec.rb
./spec/requests/api/deploy_tokens_spec.rb
- ./spec/requests/api/groups_spec.rb
./spec/requests/api/keys_spec.rb
- ./spec/requests/api/merge_requests_spec.rb
./spec/requests/api/namespaces_spec.rb
- ./spec/requests/api/notes_spec.rb
- ./spec/requests/api/personal_access_tokens/self_information_spec.rb
- ./spec/requests/api/personal_access_tokens_spec.rb
./spec/requests/api/project_export_spec.rb
./spec/requests/api/project_repository_storage_moves_spec.rb
./spec/requests/api/project_snapshots_spec.rb
./spec/requests/api/project_snippets_spec.rb
./spec/requests/api/projects_spec.rb
- ./spec/requests/api/releases_spec.rb
- ./spec/requests/api/sidekiq_metrics_spec.rb
- ./spec/requests/api/snippet_repository_storage_moves_spec.rb
./spec/requests/api/snippets_spec.rb
./spec/requests/api/statistics_spec.rb
./spec/requests/api/system_hooks_spec.rb
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index e36fafdddcc..b38fc0e68e3 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -8231,7 +8231,6 @@
- './spec/models/preloaders/merge_request_diff_preloader_spec.rb'
- './spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb'
- './spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
-- './spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- './spec/models/product_analytics_event_spec.rb'
- './spec/models/programming_language_spec.rb'
- './spec/models/project_authorization_spec.rb'
diff --git a/spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb b/spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb
index a26c20ccc61..a196b63585c 100644
--- a/spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb
@@ -17,8 +17,12 @@ RSpec.shared_examples 'a hook that gets automatically disabled on failure' do
[4, 1.second.from_now], # Exceeded the grace period, set by #backoff!
[4, Time.current] # Exceeded the grace period, set by #backoff!, edge-case
].map do |(recent_failures, disabled_until)|
- create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
-disabled_until: disabled_until)
+ create(
+ hook_factory,
+ **default_factory_arguments,
+ recent_failures: recent_failures,
+ disabled_until: disabled_until
+ )
end
end
@@ -45,8 +49,12 @@ disabled_until: disabled_until)
[0, suspended],
[0, expired]
].map do |(recent_failures, disabled_until)|
- create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
-disabled_until: disabled_until)
+ create(
+ hook_factory,
+ **default_factory_arguments,
+ recent_failures: recent_failures,
+ disabled_until: disabled_until
+ )
end
end
diff --git a/spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb b/spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb
index 9dec1a5056c..c51e4999e81 100644
--- a/spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb
@@ -112,9 +112,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the local value to be saved' do
subgroup_settings.send("#{settings_attribute_name}=", nil)
- expect { subgroup_settings.save! }
- .to raise_error(ActiveRecord::RecordInvalid,
- /cannot be changed because it is locked by an ancestor/)
+ expect { subgroup_settings.save! }.to raise_error(
+ ActiveRecord::RecordInvalid,
+ /cannot be changed because it is locked by an ancestor/
+ )
end
end
@@ -321,9 +322,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the attribute to be saved' do
subgroup_settings.send("lock_#{settings_attribute_name}=", true)
- expect { subgroup_settings.save! }
- .to raise_error(ActiveRecord::RecordInvalid,
- /cannot be changed because it is locked by an ancestor/)
+ expect { subgroup_settings.save! }.to raise_error(
+ ActiveRecord::RecordInvalid,
+ /cannot be changed because it is locked by an ancestor/
+ )
end
end
@@ -343,9 +345,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the lock to be saved when the attribute is nil' do
subgroup_settings.send("#{settings_attribute_name}=", nil)
- expect { subgroup_settings.save! }
- .to raise_error(ActiveRecord::RecordInvalid,
- /cannot be nil when locking the attribute/)
+ expect { subgroup_settings.save! }.to raise_error(
+ ActiveRecord::RecordInvalid,
+ /cannot be nil when locking the attribute/
+ )
end
it 'copies the cascaded value when locking the attribute if the local value is nil', :aggregate_failures do
@@ -364,9 +367,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the attribute to be saved' do
subgroup_settings.send("lock_#{settings_attribute_name}=", true)
- expect { subgroup_settings.save! }
- .to raise_error(ActiveRecord::RecordInvalid,
- /cannot be changed because it is locked by an ancestor/)
+ expect { subgroup_settings.save! }.to raise_error(
+ ActiveRecord::RecordInvalid,
+ /cannot be changed because it is locked by an ancestor/
+ )
end
end
diff --git a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
index 0ef9ab25505..28d2d4f1597 100644
--- a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
@@ -465,10 +465,13 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when commit comment event executed' do
let(:commit_note) do
- create(:note_on_commit, author: user,
- project: project,
- commit_id: project.repository.commit.id,
- note: 'a comment on a commit')
+ create(
+ :note_on_commit,
+ author: user,
+ project: project,
+ commit_id: project.repository.commit.id,
+ note: 'a comment on a commit'
+ )
end
let(:data) do
@@ -480,8 +483,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when merge request comment event executed' do
let(:merge_request_note) do
- create(:note_on_merge_request, project: project,
- note: 'a comment on a merge request')
+ create(:note_on_merge_request, project: project, note: 'a comment on a merge request')
end
let(:data) do
@@ -493,8 +495,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when issue comment event executed' do
let(:issue_note) do
- create(:note_on_issue, project: project,
- note: 'a comment on an issue')
+ create(:note_on_issue, project: project, note: 'a comment on an issue')
end
let(:data) do
@@ -506,8 +507,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when snippet comment event executed' do
let(:snippet_note) do
- create(:note_on_project_snippet, project: project,
- note: 'a comment on a snippet')
+ create(:note_on_project_snippet, project: project, note: 'a comment on a snippet')
end
let(:data) do
@@ -522,9 +522,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
let_it_be(:user) { create(:user) }
let_it_be_with_refind(:project) { create(:project, :repository, creator: user) }
let(:pipeline) do
- create(:ci_pipeline,
- project: project, status: status,
- sha: project.commit.sha, ref: project.default_branch)
+ create(:ci_pipeline, project: project, status: status, sha: project.commit.sha, ref: project.default_branch)
end
before do
@@ -557,9 +555,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'with failed pipeline' do
context 'on default branch' do
let(:pipeline) do
- create(:ci_pipeline,
- project: project, status: :failed,
- sha: project.commit.sha, ref: project.default_branch)
+ create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: project.default_branch)
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@@ -587,9 +583,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
end
let(:pipeline) do
- create(:ci_pipeline,
- project: project, status: :failed,
- sha: project.commit.sha, ref: 'a-protected-branch')
+ create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: 'a-protected-branch')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@@ -617,9 +611,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
end
let(:pipeline) do
- create(:ci_pipeline,
- project: project, status: :failed,
- sha: project.commit.sha, ref: '1-stable')
+ create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: '1-stable')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@@ -643,9 +635,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'on a neither protected nor default branch' do
let(:pipeline) do
- create(:ci_pipeline,
- project: project, status: :failed,
- sha: project.commit.sha, ref: 'a-random-branch')
+ create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: 'a-random-branch')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
diff --git a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
index e4958779957..b04ac40b309 100644
--- a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
@@ -84,9 +84,12 @@ RSpec.shared_examples 'a timebox' do |timebox_type|
let(:max_date) { mid_point + 10.days }
def box(from, to)
- create(factory, *timebox_args,
- start_date: from || open_on_left,
- due_date: to || open_on_right)
+ create(
+ factory,
+ *timebox_args,
+ start_date: from || open_on_left,
+ due_date: to || open_on_right
+ )
end
it 'can find overlapping timeboxes' do
diff --git a/spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb b/spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb
index 24d114bbe23..f98528ffedc 100644
--- a/spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb
@@ -18,8 +18,12 @@ RSpec.shared_examples 'a hook that does not get automatically disabled on failur
[3, nil],
[3, 1.day.ago]
].map do |(recent_failures, disabled_until)|
- create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
-disabled_until: disabled_until)
+ create(
+ hook_factory,
+ **default_factory_arguments,
+ recent_failures: recent_failures,
+ disabled_until: disabled_until
+ )
end
end
diff --git a/yarn.lock b/yarn.lock
index db5f1a23fd8..d51d8a7a545 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1048,116 +1048,6 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
-"@esbuild/android-arm64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz#52c3e6cabc19c5e4c1c0c01cb58f0442338e1c14"
- integrity sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==
-
-"@esbuild/android-arm@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.11.tgz#f3fc768235aecbeb840d0049fdf13cd28592105f"
- integrity sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==
-
-"@esbuild/android-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.11.tgz#443ed47771a7e917e4282469ba350d117473550c"
- integrity sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==
-
-"@esbuild/darwin-arm64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz#0e8c78d94d5759a48521dbfd83189d2ed3499a16"
- integrity sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==
-
-"@esbuild/darwin-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz#2405cfdf70eb961c7cf973463ca7263dc2004c88"
- integrity sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==
-
-"@esbuild/freebsd-arm64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz#d5138e873e15f87bd4564c024dfa00ef37e623fd"
- integrity sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==
-
-"@esbuild/freebsd-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz#e850b58b8fabf8e9ef0e125af3c25229ad2d6c38"
- integrity sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==
-
-"@esbuild/linux-arm64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz#2bfb93d0809ec2357c12ebb27736b750c9ae0aa5"
- integrity sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==
-
-"@esbuild/linux-arm@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz#e56fb3b76828317a704f4a167c5bd790fe5314e7"
- integrity sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==
-
-"@esbuild/linux-ia32@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz#59fa1c49b271793d14eb5effc757e8c0d0cb2cab"
- integrity sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==
-
-"@esbuild/linux-loong64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz#89575bc189099c03a36daa54f3f481780c7fd502"
- integrity sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==
-
-"@esbuild/linux-mips64el@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz#0e18ca039dc7e4645efd8edc1b10952933eb6b1b"
- integrity sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==
-
-"@esbuild/linux-ppc64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz#2d152cb3a253afb8c100a165ad132dc96f36cb11"
- integrity sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==
-
-"@esbuild/linux-riscv64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz#c6ac494a81221d53d65b33e665c7df1747952d3c"
- integrity sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==
-
-"@esbuild/linux-s390x@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz#4bad33894bc7415cea4be8fa90fe456226a424ad"
- integrity sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==
-
-"@esbuild/linux-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz#903fda743459f530a16a6c6ee8d2c0f6c1a12fc7"
- integrity sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==
-
-"@esbuild/netbsd-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz#b589239fe7d9b16ee03c5e191f3f5b640f1518a1"
- integrity sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==
-
-"@esbuild/openbsd-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz#b355019754116bef39ec688f8fd2fe6471b9779b"
- integrity sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==
-
-"@esbuild/sunos-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz#2ea47fb592e68406e5025a7696dc714fc6a115dc"
- integrity sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==
-
-"@esbuild/win32-arm64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz#47e6fdab17c4c52e6e0d606dd9cb843b29826325"
- integrity sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==
-
-"@esbuild/win32-ia32@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz#a97273aa3164c8d8f501899f55cc75a4a79599a3"
- integrity sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==
-
-"@esbuild/win32-x64@0.17.11":
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz#9be796d93ae27b636da32d960899a4912bca27a1"
- integrity sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==
-
"@eslint-community/eslint-utils@^4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz#a831e6e468b4b2b5ae42bf658bea015bf10bc518"
@@ -5512,44 +5402,6 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
-esbuild-loader@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-3.0.1.tgz#9871c0e8817c4c11b6249d1916832e75272e6c7e"
- integrity sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==
- dependencies:
- esbuild "^0.17.6"
- get-tsconfig "^4.4.0"
- loader-utils "^2.0.4"
- webpack-sources "^1.4.3"
-
-esbuild@0.17.11, esbuild@^0.17.6:
- version "0.17.11"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.11.tgz#9f3122643b21d7e7731e42f18576c10bfa28152b"
- integrity sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==
- optionalDependencies:
- "@esbuild/android-arm" "0.17.11"
- "@esbuild/android-arm64" "0.17.11"
- "@esbuild/android-x64" "0.17.11"
- "@esbuild/darwin-arm64" "0.17.11"
- "@esbuild/darwin-x64" "0.17.11"
- "@esbuild/freebsd-arm64" "0.17.11"
- "@esbuild/freebsd-x64" "0.17.11"
- "@esbuild/linux-arm" "0.17.11"
- "@esbuild/linux-arm64" "0.17.11"
- "@esbuild/linux-ia32" "0.17.11"
- "@esbuild/linux-loong64" "0.17.11"
- "@esbuild/linux-mips64el" "0.17.11"
- "@esbuild/linux-ppc64" "0.17.11"
- "@esbuild/linux-riscv64" "0.17.11"
- "@esbuild/linux-s390x" "0.17.11"
- "@esbuild/linux-x64" "0.17.11"
- "@esbuild/netbsd-x64" "0.17.11"
- "@esbuild/openbsd-x64" "0.17.11"
- "@esbuild/sunos-x64" "0.17.11"
- "@esbuild/win32-arm64" "0.17.11"
- "@esbuild/win32-ia32" "0.17.11"
- "@esbuild/win32-x64" "0.17.11"
-
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -6422,11 +6274,6 @@ get-symbol-description@^1.0.0:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"
-get-tsconfig@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5"
- integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==
-
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -8252,7 +8099,7 @@ loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2
emojis-list "^3.0.0"
json5 "^1.0.1"
-loader-utils@^2.0.0, loader-utils@^2.0.4:
+loader-utils@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==