diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:08:26 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:08:26 +0000 |
commit | 849e6f56ae6d29014a6d73f0533144adc9619e87 (patch) | |
tree | 92cc51ad6dc650ad9284de60699bb430140d3042 | |
parent | fa10e47f6e1dced92a7b28dee7fab08abeead777 (diff) | |
download | gitlab-ce-849e6f56ae6d29014a6d73f0533144adc9619e87.tar.gz |
Add latest changes from gitlab-org/gitlab@master
70 files changed, 678 insertions, 351 deletions
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml index 4c0f89e9400..fd2317f00e4 100644 --- a/.rubocop_todo/layout/argument_alignment.yml +++ b/.rubocop_todo/layout/argument_alignment.yml @@ -1763,23 +1763,6 @@ Layout/ArgumentAlignment: - 'ee/spec/views/admin/identities/index.html.haml_spec.rb' - 'ee/spec/views/groups/edit.html.haml_spec.rb' - 'ee/spec/views/projects/edit.html.haml_spec.rb' - - 'ee/spec/workers/adjourned_group_deletion_worker_spec.rb' - - 'ee/spec/workers/analytics/cycle_analytics/consistency_worker_spec.rb' - - 'ee/spec/workers/analytics/devops_adoption/create_snapshot_worker_spec.rb' - - 'ee/spec/workers/audit_events/audit_event_streaming_worker_spec.rb' - - 'ee/spec/workers/concerns/update_orchestration_policy_configuration_spec.rb' - - 'ee/spec/workers/create_github_webhook_worker_spec.rb' - - 'ee/spec/workers/ee/projects/inactive_projects_deletion_cron_worker_spec.rb' - - 'ee/spec/workers/ee/repository_check/batch_worker_spec.rb' - - 'ee/spec/workers/elastic_index_bulk_cron_worker_spec.rb' - - 'ee/spec/workers/elastic_index_initial_bulk_cron_worker_spec.rb' - - 'ee/spec/workers/epics/update_cached_metadata_worker_spec.rb' - - 'ee/spec/workers/namespaces/sync_namespace_name_worker_spec.rb' - - 'ee/spec/workers/pull_mirrors/reenable_configuration_worker_spec.rb' - - 'ee/spec/workers/repository_update_mirror_worker_spec.rb' - - 'ee/spec/workers/security/orchestration_policy_rule_schedule_namespace_worker_spec.rb' - - 'ee/spec/workers/security/orchestration_policy_rule_schedule_worker_spec.rb' - - 'ee/spec/workers/security/process_scan_result_policy_worker_spec.rb' - 'lib/api/access_requests.rb' - 'lib/api/admin/plan_limits.rb' - 'lib/api/alert_management_alerts.rb' @@ -3073,37 +3056,4 @@ Layout/ArgumentAlignment: - 'spec/views/projects/tags/index.html.haml_spec.rb' - 'spec/views/shared/milestones/_issuables.html.haml_spec.rb' - 'spec/views/shared/runners/_runner_details.html.haml_spec.rb' - - 'spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb' - - 'spec/workers/build_hooks_worker_spec.rb' - - 'spec/workers/build_queue_worker_spec.rb' - - 'spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb' - - 'spec/workers/concerns/worker_context_spec.rb' - - 'spec/workers/deployments/hooks_worker_spec.rb' - - 'spec/workers/design_management/new_version_worker_spec.rb' - - 'spec/workers/every_sidekiq_worker_spec.rb' - - 'spec/workers/integrations/irker_worker_spec.rb' - - 'spec/workers/jira_connect/sync_branch_worker_spec.rb' - - 'spec/workers/jira_connect/sync_builds_worker_spec.rb' - - 'spec/workers/jira_connect/sync_deployments_worker_spec.rb' - - 'spec/workers/jira_connect/sync_feature_flags_worker_spec.rb' - - 'spec/workers/jira_connect/sync_merge_request_worker_spec.rb' - - 'spec/workers/jira_connect/sync_project_worker_spec.rb' - - 'spec/workers/merge_requests/delete_source_branch_worker_spec.rb' - - 'spec/workers/merge_requests/update_head_pipeline_worker_spec.rb' - - 'spec/workers/namespaces/root_statistics_worker_spec.rb' - - 'spec/workers/object_pool/destroy_worker_spec.rb' - - 'spec/workers/pipeline_hooks_worker_spec.rb' - - 'spec/workers/pipeline_metrics_worker_spec.rb' - - 'spec/workers/process_commit_worker_spec.rb' - - 'spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb' - - 'spec/workers/projects/inactive_projects_deletion_notification_worker_spec.rb' - - 'spec/workers/rebase_worker_spec.rb' - - 'spec/workers/remote_mirror_notification_worker_spec.rb' - - 'spec/workers/remove_expired_members_worker_spec.rb' - - 'spec/workers/remove_unaccepted_member_invites_worker_spec.rb' - - 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb' - - 'spec/workers/repository_update_remote_mirror_worker_spec.rb' - - 'spec/workers/run_pipeline_schedule_worker_spec.rb' - - 'spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb' - - 'spec/workers/web_hook_worker_spec.rb' - 'tooling/danger/suggestor.rb' diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml index ccbbc10ad49..cc005fa9121 100644 --- a/.rubocop_todo/rspec/context_wording.yml +++ b/.rubocop_todo/rspec/context_wording.yml @@ -3164,7 +3164,6 @@ RSpec/ContextWording: - 'spec/support_specs/helpers/stub_method_calls_spec.rb' - 'spec/tasks/cache/clear/redis_spec.rb' - 'spec/tasks/dev_rake_spec.rb' - - 'spec/tasks/gettext_rake_spec.rb' - 'spec/tasks/gitlab/cleanup_rake_spec.rb' - 'spec/tasks/gitlab/db/validate_config_rake_spec.rb' - 'spec/tasks/gitlab/db_rake_spec.rb' diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml index bbd6cccef0f..af8a427c9f8 100644 --- a/.rubocop_todo/rspec/missing_feature_category.yml +++ b/.rubocop_todo/rspec/missing_feature_category.yml @@ -6079,7 +6079,6 @@ RSpec/MissingFeatureCategory: - 'spec/tasks/admin_mode_spec.rb' - 'spec/tasks/config_lint_spec.rb' - 'spec/tasks/dev_rake_spec.rb' - - 'spec/tasks/gettext_rake_spec.rb' - 'spec/tasks/gitlab/artifacts/check_rake_spec.rb' - 'spec/tasks/gitlab/artifacts/migrate_rake_spec.rb' - 'spec/tasks/gitlab/background_migrations_rake_spec.rb' diff --git a/.rubocop_todo/style/redundant_regexp_escape.yml b/.rubocop_todo/style/redundant_regexp_escape.yml index 9a54b73b64e..61592f8f4cd 100644 --- a/.rubocop_todo/style/redundant_regexp_escape.yml +++ b/.rubocop_todo/style/redundant_regexp_escape.yml @@ -77,7 +77,6 @@ Style/RedundantRegexpEscape: - 'lib/gitlab/utils/sanitize_node_link.rb' - 'lib/gitlab/word_diff/segments/diff_hunk.rb' - 'lib/product_analytics/tracker.rb' - - 'lib/tasks/gettext.rake' - 'lib/tasks/gitlab/info.rake' - 'qa/spec/runtime/key/ecdsa_spec.rb' - 'qa/spec/runtime/key/ed25519_spec.rb' diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 175d99e2170..8999666e07f 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -534e1a1c783059ab7a24ede2c63a53867ba393a2 +1017fbf2f98b23dd93d86173015159fd31df64d0 @@ -102,7 +102,7 @@ gem 'acme-client', '~> 2.0' gem 'browser', '~> 5.3.1' # OS detection for usage ping -gem 'ohai', '~> 16.10' +gem 'ohai', '~> 17.9' # GPG gem 'gpgme', '~> 2.0.22' diff --git a/Gemfile.checksum b/Gemfile.checksum index e35974b5e29..a264fe1d13a 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -396,7 +396,7 @@ {"name":"oauth","version":"0.5.6","platform":"ruby","checksum":"4085fe28e0c5e2434135e00a6555294fd2a4ff96a98d1bdecdcd619fc6368dff"}, {"name":"oauth2","version":"2.0.9","platform":"ruby","checksum":"b21f9defcf52dc1610e0dfab4c868342173dcd707fd15c777d9f4f04e153f7fb"}, {"name":"octokit","version":"4.25.1","platform":"ruby","checksum":"c02092ee82dcdfe84db0e0ea630a70d32becc54245a4f0bacfd21c010df09b96"}, -{"name":"ohai","version":"16.10.6","platform":"ruby","checksum":"b835806e585faea4ac8346b68c722fb5fc29a29f73fd7e3a022f9073132dec22"}, +{"name":"ohai","version":"17.9.0","platform":"ruby","checksum":"c59cf16124c0a6481fb85013ec7ec5b398651b6abed782d3e06ab058ce9a5406"}, {"name":"oj","version":"3.13.23","platform":"ruby","checksum":"206dfdc4020ad9974705037f269cfba211d61b7662a58c717cce771829ccef51"}, {"name":"oj-introspect","version":"0.7.2","platform":"ruby","checksum":"c415a44567ed2870d8e963a69421d9322128e194fab7867e37e54d5a25d5333d"}, {"name":"omniauth","version":"2.1.0","platform":"ruby","checksum":"bff7234f5ec9323622b217c7f26d52f850de0b0e2b8c807c3358fc79fe572300"}, diff --git a/Gemfile.lock b/Gemfile.lock index 7ef44a9e27f..f71f7f1fb1d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1000,16 +1000,16 @@ GEM octokit (4.25.1) faraday (>= 1, < 3) sawyer (~> 0.9) - ohai (16.10.6) - chef-config (>= 12.8, < 17) - chef-utils (>= 16.0, < 17) + ohai (17.9.0) + chef-config (>= 14.12, < 18) + chef-utils (>= 16.0, < 18) ffi (~> 1.9) ffi-yajl (~> 2.2) ipaddress mixlib-cli (>= 1.7.0) mixlib-config (>= 2.0, < 4.0) mixlib-log (>= 2.0.1, < 4.0) - mixlib-shellout (>= 2.0, < 4.0) + mixlib-shellout (~> 3.2, >= 3.2.5) plist (~> 3.1) train-core wmi-lite (~> 1.0) @@ -1801,7 +1801,7 @@ DEPENDENCIES nokogiri (~> 1.14.2) oauth2 (~> 2.0) octokit (~> 4.15) - ohai (~> 16.10) + ohai (~> 17.9) oj (~> 3.13.21) oj-introspect (~> 0.7) omniauth (~> 2.1.0) diff --git a/app/graphql/mutations/achievements/delete.rb b/app/graphql/mutations/achievements/delete.rb new file mode 100644 index 00000000000..0b510b44b4e --- /dev/null +++ b/app/graphql/mutations/achievements/delete.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Mutations + module Achievements + class Delete < BaseMutation + graphql_name 'AchievementsDelete' + + include Gitlab::Graphql::Authorize::AuthorizeResource + + field :achievement, + ::Types::Achievements::AchievementType, + null: true, + description: 'Achievement.' + + argument :achievement_id, ::Types::GlobalIDType[::Achievements::Achievement], + required: true, + description: 'Global ID of the achievement being deleted.' + + authorize :admin_achievement + + def resolve(args) + achievement = authorized_find!(id: args[:achievement_id]) + + result = ::Achievements::DestroyService.new(current_user, achievement).execute + { achievement: result.payload, errors: result.errors } + end + + def find_object(id:) + GitlabSchema.object_from_id(id, expected_type: ::Achievements::Achievement) + end + end + end +end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index 9bdbdad4386..43ca4f9643d 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -8,6 +8,7 @@ module Types mount_mutation Mutations::Achievements::Award, alpha: { milestone: '15.10' } mount_mutation Mutations::Achievements::Create, alpha: { milestone: '15.8' } + mount_mutation Mutations::Achievements::Delete, alpha: { milestone: '15.11' } mount_mutation Mutations::Achievements::Revoke, alpha: { milestone: '15.10' } mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs mount_mutation Mutations::AlertManagement::CreateAlertIssue diff --git a/app/helpers/protected_branches_helper.rb b/app/helpers/protected_branches_helper.rb index 07b07bfd33c..bd2a4d1170d 100644 --- a/app/helpers/protected_branches_helper.rb +++ b/app/helpers/protected_branches_helper.rb @@ -17,3 +17,5 @@ module ProtectedBranchesHelper end end end + +ProtectedBranchesHelper.prepend_mod diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index e0cf7aa61ee..75fefd12565 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -58,12 +58,23 @@ module UsersHelper end # Used to preload when you are rendering many projects and checking access - # - # rubocop: disable CodeReuse/ActiveRecord: `projects` can be array which also responds to pluck def load_max_project_member_accesses(projects) - current_user&.max_member_access_for_project_ids(projects.pluck(:id)) + # There are two different request store paradigms for max member access and + # we need to preload both of them. One is keyed User the other is keyed by + # Project. See https://gitlab.com/gitlab-org/gitlab/-/issues/396822 + + # rubocop: disable CodeReuse/ActiveRecord: `projects` can be array which also responds to pluck + project_ids = projects.pluck(:id) + # rubocop: enable CodeReuse/ActiveRecord + + if Feature.enabled?(:fix_users_helper_load_max_project_member_accesses) + Preloaders::UserMaxAccessLevelInProjectsPreloader + .new(project_ids, current_user) + .execute + end + + current_user&.max_member_access_for_project_ids(project_ids) end - # rubocop: enable CodeReuse/ActiveRecord def max_project_member_access(project) current_user&.max_member_access_for_project(project.id) || Gitlab::Access::NO_ACCESS diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index c577e2da1bb..68b15f7e042 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -22,7 +22,7 @@ module VisibilityLevelHelper when Project project_visibility_level_description(level) when Group - group_visibility_level_description(level) + group_visibility_level_description(level, form_model) end end @@ -125,22 +125,39 @@ module VisibilityLevelHelper def project_visibility_level_description(level) case level when Gitlab::VisibilityLevel::PRIVATE - _("Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group.") + s_("VisibilityLevel|Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group.") when Gitlab::VisibilityLevel::INTERNAL - _("The project can be accessed by any logged in user except external users.") + s_("VisibilityLevel|The project can be accessed by any logged in user except external users.") when Gitlab::VisibilityLevel::PUBLIC - _("The project can be accessed without any authentication.") + s_("VisibilityLevel|The project can be accessed without any authentication.") end end - def group_visibility_level_description(level) + def show_updated_public_description_for_setting(group) + group && !group.new_record? && Gitlab::CurrentSettings.current_application_settings.try(:should_check_namespace_plan?) + end + + def group_visibility_level_description(level, group = nil) case level when Gitlab::VisibilityLevel::PRIVATE - _("The group and its projects can only be viewed by members.") + s_("VisibilityLevel|The group and its projects can only be viewed by members.") when Gitlab::VisibilityLevel::INTERNAL - _("The group and any internal projects can be viewed by any logged in user except external users.") + s_("VisibilityLevel|The group and any internal projects can be viewed by any logged in user except external users.") when Gitlab::VisibilityLevel::PUBLIC - _("The group and any public projects can be viewed without any authentication.") + unless show_updated_public_description_for_setting(group) + return s_('VisibilityLevel|The group and any public projects can be viewed without any authentication.') + end + + Kernel.format( + s_( + 'VisibilityLevel|The group, any public projects, and any of their members, issues, and merge requests can be viewed without authentication. ' \ + 'Public groups and projects will be indexed by search engines. ' \ + 'Read more about %{free_user_limit_doc_link_start}free user limits%{link_end}, ' \ + 'or %{group_billings_link_start}upgrade to a paid tier%{link_end}.'), + free_user_limit_doc_link_start: "<a href='#{help_page_path('user/free_user_limit')}' target='_blank' rel='noopener noreferrer'>".html_safe, + group_billings_link_start: "<a href='#{group_billings_path(group)}' target='_blank' rel='noopener noreferrer'>".html_safe, + link_end: "</a>".html_safe + ).html_safe end end diff --git a/app/models/project.rb b/app/models/project.rb index cb218c0a49f..0c5257065c1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -168,6 +168,7 @@ class Project < ApplicationRecord alias_method :parent, :namespace alias_attribute :parent_id, :namespace_id + has_one :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :project has_one :last_event, -> { order 'events.created_at DESC' }, class_name: 'Event' has_many :boards diff --git a/app/services/achievements/destroy_service.rb b/app/services/achievements/destroy_service.rb new file mode 100644 index 00000000000..3204adb8e89 --- /dev/null +++ b/app/services/achievements/destroy_service.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Achievements + class DestroyService + attr_reader :current_user, :achievement + + def initialize(current_user, achievement) + @current_user = current_user + @achievement = achievement + end + + def execute + return error_no_permissions unless allowed? + + achievement.delete + ServiceResponse.success(payload: achievement) + end + + private + + def allowed? + current_user&.can?(:admin_achievement, achievement) + end + + def error_no_permissions + error('You have insufficient permissions to delete this achievement') + end + + def error(message) + ServiceResponse.error(message: Array(message)) + end + end +end diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb index a3289f9e552..e5883ca06f4 100644 --- a/app/services/releases/create_service.rb +++ b/app/services/releases/create_service.rb @@ -18,6 +18,12 @@ module Releases return tag unless tag.is_a?(Gitlab::Git::Tag) + if project.catalog_resource + response = Ci::Catalog::ValidateResourceService.new(project, ref).execute + + return error(response.message) if response.error? + end + create_release(tag, evidence_pipeline) end diff --git a/app/uploaders/object_storage/cdn/google_cdn.rb b/app/uploaders/object_storage/cdn/google_cdn.rb index f1fe62e9db3..f39729357ed 100644 --- a/app/uploaders/object_storage/cdn/google_cdn.rb +++ b/app/uploaders/object_storage/cdn/google_cdn.rb @@ -28,7 +28,7 @@ module ObjectStorage expiration = (Time.current + expiry).utc.to_i uri = Addressable::URI.parse(cdn_url) - uri.path = path + uri.path = Addressable::URI.encode_component(path, Addressable::URI::CharacterClasses::PATH) # Use an Array to preserve order: Google CDN needs to have # Expires, KeyName, and Signature in that order or it will return a 403 error: # https://cloud.google.com/cdn/docs/troubleshooting-steps#signing diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 74567af3554..ee3a790fde0 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -34,7 +34,6 @@ = dispensable_render_if_exists "shared/namespace_user_cap_reached_alert" = dispensable_render_if_exists "shared/new_user_signups_cap_reached_alert" = yield :page_level_alert - = yield :free_user_cap_alert = yield :group_invite_members_banner - unless @hide_breadcrumbs = render "layouts/nav/breadcrumbs" diff --git a/config/feature_flags/development/disable_update_max_seats_worker.yml b/config/feature_flags/development/arkose_labs_trial_signup_challenge.yml index ae0fe482ee9..c24a6994045 100644 --- a/config/feature_flags/development/disable_update_max_seats_worker.yml +++ b/config/feature_flags/development/arkose_labs_trial_signup_challenge.yml @@ -1,8 +1,8 @@ --- -name: disable_update_max_seats_worker -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114127 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382725 +name: arkose_labs_trial_signup_challenge +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113985 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/395754 milestone: '15.10' type: development -group: group::utilization +group: group::anti-abuse default_enabled: false diff --git a/config/feature_flags/development/fix_users_helper_load_max_project_member_accesses.yml b/config/feature_flags/development/fix_users_helper_load_max_project_member_accesses.yml new file mode 100644 index 00000000000..67d6ab8ef5a --- /dev/null +++ b/config/feature_flags/development/fix_users_helper_load_max_project_member_accesses.yml @@ -0,0 +1,8 @@ +--- +name: fix_users_helper_load_max_project_member_accesses +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114665 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/396647 +milestone: '15.11' +type: development +group: 'group::pipeline execution' +default_enabled: false diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 9cb1be45b68..701b117136c 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -761,9 +761,6 @@ Gitlab.ee do Settings.cron_jobs['ldap_sync_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['ldap_sync_worker']['cron'] ||= '30 1 * * *' Settings.cron_jobs['ldap_sync_worker']['job_class'] = 'LdapSyncWorker' - Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker'] ||= Settingslogic.new({}) - Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker']['cron'] ||= '0 12 * * *' - Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker']['job_class'] = 'UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker' Settings.cron_jobs['elastic_index_bulk_cron_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['elastic_index_bulk_cron_worker']['cron'] ||= '*/1 * * * *' Settings.cron_jobs['elastic_index_bulk_cron_worker']['job_class'] ||= 'ElasticIndexBulkCronWorker' diff --git a/data/whats_new/20230222001_15_09.yml b/data/whats_new/20230222001_15_09.yml index 217212297bb..12f771f397f 100644 --- a/data/whats_new/20230222001_15_09.yml +++ b/data/whats_new/20230222001_15_09.yml @@ -7,7 +7,7 @@ available_in: [Ultimate] documentation_link: https://docs.gitlab.com/ee/user/permissions.html#custom-roles image_url: https://img.youtube.com/vi/46cp_-Rtxps/hqdefault.jpg - published_at: 2023-02-02 # YYYY-MM-DD + published_at: 2023-02-22 # YYYY-MM-DD release: 15.9 - name: Manage license approval policies description: | # Do not modify this line, instead modify the lines below. @@ -26,7 +26,7 @@ available_in: [Ultimate] documentation_link: https://docs.gitlab.com/ee/user/compliance/license_approval_policies.html image_url: https://img.youtube.com/vi/34qBQ9t8qO8/hqdefault.jpg - published_at: 2023-02-02 # YYYY-MM-DD + published_at: 2023-02-22 # YYYY-MM-DD release: 15.9 - name: New License Compliance scanner description: | # Do not modify this line, instead modify the lines below. @@ -41,7 +41,7 @@ available_in: [Ultimate] documentation_link: https://docs.gitlab.com/ee/user/compliance/license_scanning_of_cyclonedx_files/ image_url: https://about.gitlab.com/images/15_9/new_license_scanner.png - published_at: 2023-02-02 # YYYY-MM-DD + published_at: 2023-02-22 # YYYY-MM-DD release: 15.9 - name: Notifications now available in the GitLab for Slack app description: | # Do not modify this line, instead modify the lines below. @@ -56,7 +56,7 @@ available_in: [Free, Premium, Ultimate] documentation_link: https://docs.gitlab.com/ee/user/project/integrations/gitlab_slack_application.html#slack-notifications image_url: https://about.gitlab.com/images/15_9/slack_notifications_jan_31-optimized.png - published_at: 2023-02-02 # YYYY-MM-DD + published_at: 2023-02-22 # YYYY-MM-DD release: 15.9 - name: Code Suggestions available in closed beta description: | # Do not modify this line, instead modify the lines below. @@ -71,5 +71,5 @@ available_in: [Ultimate] documentation_link: https://about.gitlab.com/releases/2023/02/22/gitlab-15-9-released/#code-suggestions-available-in-closed-beta image_url: https://about.gitlab.com/images/15_9/DemoFastApi.gif - published_at: 2023-02-02 # YYYY-MM-DD + published_at: 2023-02-22 # YYYY-MM-DD release: 15.9 diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 27da9f2b653..312e8894071 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -795,6 +795,29 @@ Input type: `AchievementsCreateInput` | <a id="mutationachievementscreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationachievementscreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +### `Mutation.achievementsDelete` + +WARNING: +**Introduced** in 15.11. +This feature is in Alpha. It can be changed or removed at any time. + +Input type: `AchievementsDeleteInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationachievementsdeleteachievementid"></a>`achievementId` | [`AchievementsAchievementID!`](#achievementsachievementid) | Global ID of the achievement being deleted. | +| <a id="mutationachievementsdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationachievementsdeleteachievement"></a>`achievement` | [`Achievement`](#achievement) | Achievement. | +| <a id="mutationachievementsdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| <a id="mutationachievementsdeleteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | + ### `Mutation.achievementsRevoke` WARNING: diff --git a/doc/user/analytics/dora_metrics.md b/doc/user/analytics/dora_metrics.md index b85ec60f00e..0fdb4ea6948 100644 --- a/doc/user/analytics/dora_metrics.md +++ b/doc/user/analytics/dora_metrics.md @@ -140,7 +140,7 @@ The DORA metrics are displayed on the following charts: The table below provides an overview of the DORA metrics' data aggregation in different charts. -| Metric name | Measured values | Data aggregation in the [Value Streams Dashboard](value_streams_dashboard.md) | Data aggregation in CI/CD analytics charts | Data aggregation in Value stream analytics | Data aggregation in Custom insights reporting | +| Metric name | Measured values | Data aggregation in the [Value Streams Dashboard](value_streams_dashboard.md) | Data aggregation in [CI/CD analytics charts](ci_cd_analytics.md) | Data aggregation in Value stream analytics | Data aggregation in [Custom insights reporting](../../user/project/insights/index.md#dora-query-parameters) | |---------------------------|-------------------|-----------------------------------------------------|------------------------|-----------------------|----------| | Deployment frequency | Number of successful deployments | daily average per month | daily average | daily average | `day` (default) or `month` | | Lead time for changes | Number of seconds to successfully deliver a commit into production | daily median per month | median time | median time | `day` (default) or `month` | diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake index 17f9414ad52..5b95057488c 100644 --- a/lib/tasks/gettext.rake +++ b/lib/tasks/gettext.rake @@ -11,45 +11,23 @@ namespace :gettext do end desc 'Regenerate gitlab.pot file' - task :regenerate do + task regenerate: ['gettext:setup'] do ensure_locale_folder_presence! - # Clean up folders that do not contain a gitlab.po file - Pathname.new(locale_path).children.each do |child| - next unless child.directory? - - folder_path = child.to_path - - if File.exist?("#{folder_path}/gitlab.po") - # remove all translated files to speed up finding - FileUtils.rm Dir["#{folder_path}/gitlab.*"] - else - # remove empty translation folders so we don't generate un-needed .po files - puts "Deleting #{folder_path} as it does not contain a 'gitlab.po' file." - - FileUtils.rm_r folder_path - end - end - # remove the `pot` file to ensure it's completely regenerated FileUtils.rm_f(pot_file_path) - Rake::Task['gettext:find'].invoke - - # leave only the required changes. - unless system(*%w(git -c core.hooksPath=/dev/null checkout -- locale/*/gitlab.po)) - raise 'failed to cleanup generated locale/*/gitlab.po files' - end + Rake::Task['gettext:pot:create'].invoke raise 'gitlab.pot file not generated' unless File.exist?(pot_file_path) # Remove timestamps from the pot file pot_content = File.read pot_file_path - pot_content.gsub!(/^"POT?\-(?:Creation|Revision)\-Date\:.*\n/, '') + pot_content.gsub!(/^"POT?-(?:Creation|Revision)-Date:.*\n/, '') File.write pot_file_path, pot_content puts <<~MSG - All done. Please commit the changes to `locale/gitlab.pot`. + All done. Please commit the changes to `locale/gitlab.pot`. MSG end @@ -86,19 +64,7 @@ namespace :gettext do end end - task :updated_check do - # Removing all pre-translated files speeds up `gettext:find` as the - # files don't need to be merged. - # Having `LC_MESSAGES/gitlab.mo files present also confuses the output. - FileUtils.rm Dir['locale/**/gitlab.*'] - FileUtils.rm_f pot_file_path - - # `gettext:find` writes touches to temp files to `stderr` which would cause - # `static-analysis` to report failures. We can ignore these. - silence_stderr do - Rake::Task['gettext:find'].invoke - end - + task updated_check: [:regenerate] do pot_diff = `git diff -- #{pot_file_path} | grep -E '^(\\+|-)msgid'`.strip # reset the locale folder for potential next tasks @@ -159,7 +125,7 @@ namespace :gettext do def ensure_locale_folder_presence! unless Dir.exist?(locale_path) raise <<~MSG - Cannot find '#{locale_path}' folder. Please ensure you're running this task from the gitlab repo. + Cannot find '#{locale_path}' folder. Please ensure you're running this task from the gitlab repo. MSG end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ca757c57f3b..70b7d41de42 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -33673,9 +33673,6 @@ msgstr "" msgid "Project URL" msgstr "" -msgid "Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group." -msgstr "" - msgid "Project access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}" msgstr "" @@ -43627,15 +43624,6 @@ msgstr "" msgid "The global settings require you to enable Two-Factor Authentication for your account." msgstr "" -msgid "The group and any internal projects can be viewed by any logged in user except external users." -msgstr "" - -msgid "The group and any public projects can be viewed without any authentication." -msgstr "" - -msgid "The group and its projects can only be viewed by members." -msgstr "" - msgid "The group export can be downloaded from:" msgstr "" @@ -43795,12 +43783,6 @@ msgstr "" msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user." msgstr "" -msgid "The project can be accessed by any logged in user except external users." -msgstr "" - -msgid "The project can be accessed without any authentication." -msgstr "" - msgid "The project has already been added to your dashboard." msgstr "" @@ -48058,9 +48040,30 @@ msgstr "" msgid "VisibilityLevel|Private" msgstr "" +msgid "VisibilityLevel|Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group." +msgstr "" + msgid "VisibilityLevel|Public" msgstr "" +msgid "VisibilityLevel|The group and any internal projects can be viewed by any logged in user except external users." +msgstr "" + +msgid "VisibilityLevel|The group and any public projects can be viewed without any authentication." +msgstr "" + +msgid "VisibilityLevel|The group and its projects can only be viewed by members." +msgstr "" + +msgid "VisibilityLevel|The group, any public projects, and any of their members, issues, and merge requests can be viewed without authentication. Public groups and projects will be indexed by search engines. Read more about %{free_user_limit_doc_link_start}free user limits%{link_end}, or %{group_billings_link_start}upgrade to a paid tier%{link_end}." +msgstr "" + +msgid "VisibilityLevel|The project can be accessed by any logged in user except external users." +msgstr "" + +msgid "VisibilityLevel|The project can be accessed without any authentication." +msgstr "" + msgid "VisibilityLevel|Unknown" msgstr "" diff --git a/spec/graphql/mutations/achievements/delete_spec.rb b/spec/graphql/mutations/achievements/delete_spec.rb new file mode 100644 index 00000000000..0eb6f5a2e6f --- /dev/null +++ b/spec/graphql/mutations/achievements/delete_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Achievements::Delete, feature_category: :user_profile do + include GraphqlHelpers + + let_it_be(:developer) { create(:user) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:recipient) { create(:user) } + let_it_be(:group) { create(:group) } + + let(:achievement) { create(:achievement, namespace: group) } + + describe '#resolve' do + subject(:resolve_mutation) do + described_class.new(object: nil, context: { current_user: current_user }, field: nil).resolve( + achievement_id: achievement&.to_global_id + ) + end + + before_all do + group.add_developer(developer) + group.add_maintainer(maintainer) + end + + context 'when the user does not have permission' do + let(:current_user) { developer } + + it 'raises an error' do + expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + .with_message(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR) + end + end + + context 'when the user has permission' do + let(:current_user) { maintainer } + + context 'when the params are invalid' do + let(:achievement) { nil } + + it 'returns the validation error' do + expect { resolve_mutation }.to raise_error { Gitlab::Graphql::Errors::ArgumentError } + end + end + + it 'deletes the achievement' do + resolve_mutation + + expect(Achievements::Achievement.find_by(id: achievement.id)).to be_nil + end + end + end + + specify { expect(described_class).to require_graphql_authorizations(:admin_achievement) } +end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 2829236f7d1..e1f474a0a3e 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -524,4 +524,54 @@ RSpec.describe UsersHelper do }) end end + + describe '#load_max_project_member_accesses' do + let_it_be(:projects) { create_list(:project, 3) } + + before(:all) do + projects.first.add_developer(user) + end + + context 'without current_user' do + before do + allow(helper).to receive(:current_user).and_return(nil) + end + + it 'executes no queries' do + sample = ActiveRecord::QueryRecorder.new do + helper.load_max_project_member_accesses(projects) + end + + expect(sample).not_to exceed_query_limit(0) + end + end + + context 'when current_user is present', :request_store do + before do + allow(helper).to receive(:current_user).and_return(user) + end + + it 'preloads ProjectPolicy#lookup_access_level! and UsersHelper#max_member_project_member_access for current_user in two queries', :aggregate_failures do + preload_queries = ActiveRecord::QueryRecorder.new do + helper.load_max_project_member_accesses(projects) + end + + helper_queries = ActiveRecord::QueryRecorder.new do + projects.each do |project| + helper.max_project_member_access(project) + end + end + + access_queries = ActiveRecord::QueryRecorder.new do + projects.each do |project| + user.can?(:read_code, project) + end + end + + expect(preload_queries).not_to exceed_query_limit(2) + expect(helper_queries).not_to exceed_query_limit(0) + expect(access_queries).not_to exceed_query_limit(0) + end + end + end end diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 2aac0cae0c6..a0bd629e3e6 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe VisibilityLevelHelper do +RSpec.describe VisibilityLevelHelper, feature_category: :system_access do include ProjectForksHelper let(:project) { build(:project) } @@ -78,6 +78,23 @@ RSpec.describe VisibilityLevelHelper do expect(descriptions.uniq.size).to eq(descriptions.size) expect(descriptions).to all match /group/i end + + it 'returns default description for public group' do + expect(descriptions[2]).to eq('The group and any public projects can be viewed without any authentication.') + end + + context 'when application setting `should_check_namespace_plan` is true', if: Gitlab.ee? do + let(:group) { create(:group) } + let(:public_option_description) { visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, group) } + + before do + allow(Gitlab::CurrentSettings.current_application_settings).to receive(:should_check_namespace_plan?) { true } + end + + it 'returns updated description for public visibility option in group general settings' do + expect(public_option_description).to match /^The group, any public projects, and any of their members, issues, and merge requests can be viewed without authentication./ + end + end end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index f6d6a791e8c..bcdbf3d58d0 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -493,6 +493,7 @@ container_repositories: - project - name project: +- catalog_resource - external_status_checks - base_tags - project_topics @@ -998,3 +999,5 @@ resource_iteration_events: iterations_cadence: - group - iterations +catalog_resource: + - project diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 15e5db5af60..caaf85c79c3 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -43,6 +43,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do it { is_expected.to have_many(:exported_protected_branches) } it { is_expected.to have_one(:wiki_repository).class_name('Projects::WikiRepository').inverse_of(:project) } it { is_expected.to have_one(:slack_integration) } + it { is_expected.to have_one(:catalog_resource) } it { is_expected.to have_one(:microsoft_teams_integration) } it { is_expected.to have_one(:mattermost_integration) } it { is_expected.to have_one(:hangouts_chat_integration) } diff --git a/spec/requests/api/graphql/mutations/achievements/delete_spec.rb b/spec/requests/api/graphql/mutations/achievements/delete_spec.rb new file mode 100644 index 00000000000..276da4f46a8 --- /dev/null +++ b/spec/requests/api/graphql/mutations/achievements/delete_spec.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Achievements::Delete, feature_category: :user_profile do + include GraphqlHelpers + + let_it_be(:developer) { create(:user) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:group) { create(:group) } + + let!(:achievement) { create(:achievement, namespace: group) } + let(:mutation) { graphql_mutation(:achievements_delete, params) } + let(:achievement_id) { achievement&.to_global_id } + let(:params) { { achievement_id: achievement_id } } + + subject { post_graphql_mutation(mutation, current_user: current_user) } + + def mutation_response + graphql_mutation_response(:achievements_delete) + end + + before_all do + group.add_developer(developer) + group.add_maintainer(maintainer) + end + + context 'when the user does not have permission' do + let(:current_user) { developer } + + it_behaves_like 'a mutation that returns a top-level access error' + + it 'does not revoke any achievements' do + expect { subject }.not_to change { Achievements::Achievement.count } + end + end + + context 'when the user has permission' do + let(:current_user) { maintainer } + + context 'when the params are invalid' do + let(:achievement) { nil } + + it 'returns the validation error' do + subject + + expect(graphql_errors.to_s).to include('invalid value for achievementId (Expected value to not be null)') + end + end + + context 'when the achievement_id is invalid' do + let(:achievement_id) { "gid://gitlab/Achievements::Achievement/#{non_existing_record_id}" } + + it 'returns the validation error' do + subject + + expect(graphql_errors.to_s) + .to include("The resource that you are attempting to access does not exist or you don't have permission") + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(achievements: false) + end + + it 'returns the relevant error' do + subject + + expect(graphql_errors.to_s) + .to include("The resource that you are attempting to access does not exist or you don't have permission") + end + end + + it 'deletes the achievement' do + expect { subject }.to change { Achievements::Achievement.count }.by(-1) + end + end +end diff --git a/spec/services/achievements/destroy_service_spec.rb b/spec/services/achievements/destroy_service_spec.rb new file mode 100644 index 00000000000..7af10ceec6a --- /dev/null +++ b/spec/services/achievements/destroy_service_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Achievements::DestroyService, feature_category: :user_profile do + describe '#execute' do + let_it_be(:developer) { create(:user) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:group) { create(:group) } + + let(:achievement) { create(:achievement, namespace: group) } + + subject(:response) { described_class.new(current_user, achievement).execute } + + before_all do + group.add_developer(developer) + group.add_maintainer(maintainer) + end + + context 'when user does not have permission' do + let(:current_user) { developer } + + it 'returns an error' do + expect(response).to be_error + expect(response.message).to match_array( + ['You have insufficient permissions to delete this achievement']) + end + end + + context 'when user has permission' do + let(:current_user) { maintainer } + + it 'deletes the achievement' do + expect(response).to be_success + expect(Achievements::Achievement.find_by(id: achievement.id)).to be_nil + end + end + end +end diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb index 9768ceb12e8..ca5dd912e77 100644 --- a/spec/services/releases/create_service_spec.rb +++ b/spec/services/releases/create_service_spec.rb @@ -55,6 +55,26 @@ RSpec.describe Releases::CreateService, feature_category: :continuous_integratio end end + context 'when project is a catalog resource' do + let(:ref) { 'master' } + let!(:catalog_resource) { create(:catalog_resource, project: project) } + + context 'and it is valid' do + let_it_be(:project) { create(:project, :repository, description: 'our components') } + + it_behaves_like 'a successful release creation' + end + + context 'and it is invalid' do + it 'raises an error and does not update the release' do + result = service.execute + + expect(result[:status]).to eq(:error) + expect(result[:message]).to eq('Project must have a description') + end + end + end + context 'when ref is provided' do let(:ref) { 'master' } let(:tag_name) { 'foobar' } diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 74b80c4864c..e36fafdddcc 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -3310,7 +3310,6 @@ - './ee/spec/workers/sync_seat_link_worker_spec.rb' - './ee/spec/workers/todos_destroyer/confidential_epic_worker_spec.rb' - './ee/spec/workers/update_all_mirrors_worker_spec.rb' -- './ee/spec/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker_spec.rb' - './ee/spec/workers/vulnerabilities/historical_statistics/deletion_worker_spec.rb' - './ee/spec/workers/vulnerabilities/statistics/adjustment_worker_spec.rb' - './ee/spec/workers/vulnerabilities/statistics/schedule_worker_spec.rb' @@ -10049,7 +10048,6 @@ - './spec/tasks/cache/clear/redis_spec.rb' - './spec/tasks/config_lint_spec.rb' - './spec/tasks/dev_rake_spec.rb' -- './spec/tasks/gettext_rake_spec.rb' - './spec/tasks/gitlab/artifacts/check_rake_spec.rb' - './spec/tasks/gitlab/artifacts/migrate_rake_spec.rb' - './spec/tasks/gitlab/background_migrations_rake_spec.rb' diff --git a/spec/tasks/gettext_rake_spec.rb b/spec/tasks/gettext_rake_spec.rb index 29caa363f7b..d35beef0484 100644 --- a/spec/tasks/gettext_rake_spec.rb +++ b/spec/tasks/gettext_rake_spec.rb @@ -2,7 +2,7 @@ require 'rake_helper' -RSpec.describe 'gettext', :silence_stdout do +RSpec.describe 'gettext', :silence_stdout, feature_category: :internationalization do let(:locale_path) { Rails.root.join('tmp/gettext_spec') } let(:pot_file_path) { File.join(locale_path, 'gitlab.pot') } @@ -35,9 +35,16 @@ RSpec.describe 'gettext', :silence_stdout do end describe ':regenerate' do + let(:locale_nz_path) { File.join(locale_path, 'en_NZ') } + let(:po_file_path) { File.join(locale_nz_path, 'gitlab.po') } + before do + FileUtils.mkdir(locale_nz_path) + File.write(po_file_path, fixture_file('valid.po')) + + Rake::Task['gettext:setup'].invoke # this task takes a *really* long time to complete, so stub it for the spec - allow(Rake::Task['gettext:find']).to receive(:invoke) { invoke_find.call } + allow(Rake::Task['gettext:pot:create']).to receive(:invoke) { invoke_find.call } end context 'when the locale folder is not found' do @@ -53,39 +60,6 @@ RSpec.describe 'gettext', :silence_stdout do end end - context 'where there are existing /**/gitlab.po files' do - let(:locale_nz_path) { File.join(locale_path, 'en_NZ') } - let(:po_file_path) { File.join(locale_nz_path, 'gitlab.po') } - - let(:invoke_find) { -> { File.write pot_file_path, 'pot file test updates' } } - - before do - FileUtils.mkdir(locale_nz_path) - File.write(po_file_path, fixture_file('valid.po')) - end - - it 'does not remove that locale' do - expect { run_rake_task('gettext:regenerate') } - .not_to change { Dir.exist?(locale_nz_path) } - end - end - - context 'when there are locale folders without a gitlab.po file' do - let(:empty_locale_path) { File.join(locale_path, 'en_NZ') } - - let(:invoke_find) { -> { File.write pot_file_path, 'pot file test updates' } } - - before do - FileUtils.mkdir(empty_locale_path) - end - - it 'removes those folders' do - expect { run_rake_task('gettext:regenerate') } - .to change { Dir.exist?(empty_locale_path) } - .to eq false - end - end - context 'when the gitlab.pot file cannot be generated' do let(:invoke_find) { -> { true } } @@ -95,7 +69,7 @@ RSpec.describe 'gettext', :silence_stdout do end end - context 'when gettext:find changes the revision dates' do + context 'when gettext:pot:create changes the revision dates' do let(:invoke_find) { -> { File.write pot_file_path, fixture_file('valid.po') } } before do diff --git a/spec/uploaders/object_storage/cdn/google_cdn_spec.rb b/spec/uploaders/object_storage/cdn/google_cdn_spec.rb index 184c664f6dc..96413f622e8 100644 --- a/spec/uploaders/object_storage/cdn/google_cdn_spec.rb +++ b/spec/uploaders/object_storage/cdn/google_cdn_spec.rb @@ -99,9 +99,10 @@ RSpec.describe ObjectStorage::CDN::GoogleCDN, let(:path) { '/path/to/file.txt' } let(:expiration) { (Time.current + 10.minutes).utc.to_i } let(:cdn_query_params) { "Expires=#{expiration}&KeyName=#{key_name}" } + let(:encoded_path) { Addressable::URI.encode_component(path, Addressable::URI::CharacterClasses::PATH) } def verify_signature(url, unsigned_url) - expect(url).to start_with("#{options[:url]}#{path}") + expect(url).to start_with("#{options[:url]}#{encoded_path}") uri = Addressable::URI.parse(url) query = uri.query_values @@ -116,6 +117,16 @@ RSpec.describe ObjectStorage::CDN::GoogleCDN, end end + context 'with UTF-8 characters in path' do + let(:path) { "/path/to/©️job🧪" } + let(:url) { subject.signed_url(path) } + let(:unsigned_url) { "#{options[:url]}#{encoded_path}?#{cdn_query_params}" } + + it 'returns a valid signed URL' do + verify_signature(url, unsigned_url) + end + end + context 'with default query parameters' do let(:url) { subject.signed_url(path) } let(:unsigned_url) { "#{options[:url]}#{path}?#{cdn_query_params}" } diff --git a/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb b/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb index 081bece09e9..fcc157f9998 100644 --- a/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb +++ b/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb @@ -10,9 +10,7 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker, feature_ let(:end_user_id) { start_user_id } let(:execute_worker) { subject.perform(start_user_id, end_user_id) } - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do context 'checks if project authorization update is required' do diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index f8efc9c455d..adae0417a9a 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -42,7 +42,5 @@ RSpec.describe BuildHooksWorker, feature_category: :continuous_integration do end end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed end diff --git a/spec/workers/build_queue_worker_spec.rb b/spec/workers/build_queue_worker_spec.rb index 1f3640e7496..079e11acde3 100644 --- a/spec/workers/build_queue_worker_spec.rb +++ b/spec/workers/build_queue_worker_spec.rb @@ -24,7 +24,5 @@ RSpec.describe BuildQueueWorker, feature_category: :continuous_integration do end end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :sticky + it_behaves_like 'worker with data consistency', described_class, data_consistency: :sticky end diff --git a/spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb b/spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb index bbc2bcf9ac9..9c3d249c6aa 100644 --- a/spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb +++ b/spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb @@ -9,8 +9,7 @@ RSpec.describe Ci::JobArtifacts::TrackArtifactReportWorker, feature_category: :c let_it_be(:user) { create(:user) } let_it_be(:pipeline) do - create(:ci_pipeline, :with_test_reports, :with_coverage_reports, - project: project, user: user) + create(:ci_pipeline, :with_test_reports, :with_coverage_reports, project: project, user: user) end subject(:perform) { described_class.new.perform(pipeline_id) } diff --git a/spec/workers/concerns/worker_context_spec.rb b/spec/workers/concerns/worker_context_spec.rb index 0bbe14842bb..700d9e37a55 100644 --- a/spec/workers/concerns/worker_context_spec.rb +++ b/spec/workers/concerns/worker_context_spec.rb @@ -73,9 +73,11 @@ RSpec.describe WorkerContext, feature_category: :shared do describe '.bulk_perform_async_with_contexts' do subject do - worker.bulk_perform_async_with_contexts(%w(hello world), - context_proc: -> (_) { { user: build_stubbed(:user) } }, - arguments_proc: -> (word) { word }) + worker.bulk_perform_async_with_contexts( + %w(hello world), + context_proc: -> (_) { { user: build_stubbed(:user) } }, + arguments_proc: -> (word) { word } + ) end it 'calls bulk_perform_async with the arguments' do @@ -89,10 +91,12 @@ RSpec.describe WorkerContext, feature_category: :shared do describe '.bulk_perform_in_with_contexts' do subject do - worker.bulk_perform_in_with_contexts(10.minutes, - %w(hello world), - context_proc: -> (_) { { user: build_stubbed(:user) } }, - arguments_proc: -> (word) { word }) + worker.bulk_perform_in_with_contexts( + 10.minutes, + %w(hello world), + context_proc: -> (_) { { user: build_stubbed(:user) } }, + arguments_proc: -> (word) { word } + ) end it 'calls bulk_perform_in with the arguments and delay' do diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb index 51614f8b0cb..e620ed6e05c 100644 --- a/spec/workers/deployments/hooks_worker_spec.rb +++ b/spec/workers/deployments/hooks_worker_spec.rb @@ -60,8 +60,6 @@ RSpec.describe Deployments::HooksWorker, feature_category: :continuous_delivery worker.perform(deployment_id: deployment.id, status_changed_at: status_changed_at) end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed end end diff --git a/spec/workers/design_management/new_version_worker_spec.rb b/spec/workers/design_management/new_version_worker_spec.rb index afc908d925a..baf6409a64f 100644 --- a/spec/workers/design_management/new_version_worker_spec.rb +++ b/spec/workers/design_management/new_version_worker_spec.rb @@ -57,9 +57,11 @@ RSpec.describe DesignManagement::NewVersionWorker, feature_category: :design_man context 'the version includes multiple types of action' do let_it_be(:version) do - create(:design_version, :with_lfs_file, - created_designs: create_list(:design, 1, :with_lfs_file), - modified_designs: create_list(:design, 1)) + create( + :design_version, :with_lfs_file, + created_designs: create_list(:design, 1, :with_lfs_file), + modified_designs: create_list(:design, 1) + ) end it 'creates two system notes' do diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index f080e2ef1c3..86e50bf3f97 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -493,7 +493,7 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do it 'uses specified numbers of retries for workers with exceptions encoded here', :aggregate_failures do retry_exception_workers.each do |worker| expect(worker.retries).to eq(retry_exceptions[worker.klass.to_s]), - "#{worker.klass} has #{worker.retries} retries, expected #{retry_exceptions[worker.klass]}" + "#{worker.klass} has #{worker.retries} retries, expected #{retry_exceptions[worker.klass]}" end end end diff --git a/spec/workers/integrations/irker_worker_spec.rb b/spec/workers/integrations/irker_worker_spec.rb index 257a6f72709..7a51e9cfe47 100644 --- a/spec/workers/integrations/irker_worker_spec.rb +++ b/spec/workers/integrations/irker_worker_spec.rb @@ -88,10 +88,11 @@ RSpec.describe Integrations::IrkerWorker, '#perform', feature_category: :integra context 'with new commits to existing branch' do it 'sends a correct message with a compare url' do - compare_url = Gitlab::Routing.url_helpers - .project_compare_url(project, - from: Commit.truncate_sha(push_data[:before]), - to: Commit.truncate_sha(push_data[:after])) + compare_url = Gitlab::Routing.url_helpers.project_compare_url( + project, + from: Commit.truncate_sha(push_data[:before]), + to: Commit.truncate_sha(push_data[:after]) + ) message = "pushed #{push_data['total_commits_count']} " \ "new commits to master: #{compare_url}" diff --git a/spec/workers/jira_connect/sync_branch_worker_spec.rb b/spec/workers/jira_connect/sync_branch_worker_spec.rb index 54b1915b253..1c2661ad0e5 100644 --- a/spec/workers/jira_connect/sync_branch_worker_spec.rb +++ b/spec/workers/jira_connect/sync_branch_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncBranchWorker, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:group) { create(:group) } diff --git a/spec/workers/jira_connect/sync_builds_worker_spec.rb b/spec/workers/jira_connect/sync_builds_worker_spec.rb index 6ef15b084a3..8c694fe33bd 100644 --- a/spec/workers/jira_connect/sync_builds_worker_spec.rb +++ b/spec/workers/jira_connect/sync_builds_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncBuildsWorker, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:pipeline) { create(:ci_pipeline) } diff --git a/spec/workers/jira_connect/sync_deployments_worker_spec.rb b/spec/workers/jira_connect/sync_deployments_worker_spec.rb index 2e72a94bc1e..39609f331d0 100644 --- a/spec/workers/jira_connect/sync_deployments_worker_spec.rb +++ b/spec/workers/jira_connect/sync_deployments_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncDeploymentsWorker, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:deployment) { create(:deployment) } diff --git a/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb b/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb index c2dbd52398f..cc3867d26c1 100644 --- a/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb +++ b/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncFeatureFlagsWorker, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:feature_flag) { create(:operations_feature_flag) } diff --git a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb index 23abb915d68..117dfe49b62 100644 --- a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb +++ b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncMergeRequestWorker, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:group) { create(:group) } diff --git a/spec/workers/jira_connect/sync_project_worker_spec.rb b/spec/workers/jira_connect/sync_project_worker_spec.rb index afd56a3b5c1..f559a3e1c12 100644 --- a/spec/workers/jira_connect/sync_project_worker_spec.rb +++ b/spec/workers/jira_connect/sync_project_worker_spec.rb @@ -5,9 +5,7 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncProjectWorker, factory_default: :keep, feature_category: :integrations do include AfterNextHelpers - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed describe '#perform' do let_it_be(:project) { create_default(:project).freeze } diff --git a/spec/workers/merge_requests/delete_source_branch_worker_spec.rb b/spec/workers/merge_requests/delete_source_branch_worker_spec.rb index d8e49f444a9..57f8cfbfb83 100644 --- a/spec/workers/merge_requests/delete_source_branch_worker_spec.rb +++ b/spec/workers/merge_requests/delete_source_branch_worker_spec.rb @@ -12,8 +12,11 @@ RSpec.describe MergeRequests::DeleteSourceBranchWorker, feature_category: :sourc describe '#perform' do before do allow_next_instance_of(::Projects::DeleteBranchWorker) do |instance| - allow(instance).to receive(:perform).with(merge_request.source_project.id, user.id, - merge_request.source_branch) + allow(instance).to receive(:perform).with( + merge_request.source_project.id, + user.id, + merge_request.source_branch + ) end end @@ -36,8 +39,11 @@ RSpec.describe MergeRequests::DeleteSourceBranchWorker, feature_category: :sourc context 'with existing user and merge request' do it 'calls delete branch worker' do expect_next_instance_of(::Projects::DeleteBranchWorker) do |instance| - expect(instance).to receive(:perform).with(merge_request.source_project.id, user.id, - merge_request.source_branch) + expect(instance).to receive(:perform).with( + merge_request.source_project.id, + user.id, + merge_request.source_branch + ) end worker.perform(merge_request.id, sha, user.id) diff --git a/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb index 912afb59412..b65bd4eb1db 100644 --- a/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb +++ b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb @@ -74,9 +74,12 @@ RSpec.describe MergeRequests::UpdateHeadPipelineWorker, feature_category: :code_ context 'when there is no pipeline for source branch' do it "does not update merge request head pipeline" do - merge_request = create(:merge_request, source_branch: 'feature', - target_branch: "branch_1", - source_project: project) + merge_request = create( + :merge_request, + source_branch: 'feature', + target_branch: "branch_1", + source_project: project + ) subject @@ -96,10 +99,13 @@ RSpec.describe MergeRequests::UpdateHeadPipelineWorker, feature_category: :code_ end it 'updates head pipeline for merge request' do - merge_request = create(:merge_request, source_branch: 'feature', - target_branch: "master", - source_project: project, - target_project: target_project) + merge_request = create( + :merge_request, + source_branch: 'feature', + target_branch: "master", + source_project: project, + target_project: target_project + ) subject @@ -109,9 +115,12 @@ RSpec.describe MergeRequests::UpdateHeadPipelineWorker, feature_category: :code_ context 'when the pipeline is not the latest for the branch' do it 'does not update merge request head pipeline' do - merge_request = create(:merge_request, source_branch: 'master', - target_branch: "branch_1", - source_project: project) + merge_request = create( + :merge_request, + source_branch: 'master', + target_branch: "branch_1", + source_project: project + ) create(:ci_pipeline, project: pipeline.project, ref: pipeline.ref) @@ -127,9 +136,12 @@ RSpec.describe MergeRequests::UpdateHeadPipelineWorker, feature_category: :code_ end it 'updates merge request head pipeline reference' do - merge_request = create(:merge_request, source_branch: 'master', - target_branch: 'feature', - source_project: project) + merge_request = create( + :merge_request, + source_branch: 'master', + target_branch: 'feature', + source_project: project + ) subject diff --git a/spec/workers/namespaces/root_statistics_worker_spec.rb b/spec/workers/namespaces/root_statistics_worker_spec.rb index 8409fffca26..edea9132850 100644 --- a/spec/workers/namespaces/root_statistics_worker_spec.rb +++ b/spec/workers/namespaces/root_statistics_worker_spec.rb @@ -90,9 +90,7 @@ RSpec.describe Namespaces::RootStatisticsWorker, '#perform', feature_category: : end end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :sticky + it_behaves_like 'worker with data consistency', described_class, data_consistency: :sticky it 'has the `until_executed` deduplicate strategy' do expect(described_class.get_deduplicate_strategy).to eq(:until_executed) diff --git a/spec/workers/object_pool/destroy_worker_spec.rb b/spec/workers/object_pool/destroy_worker_spec.rb index f83d3814c63..7db3404ed36 100644 --- a/spec/workers/object_pool/destroy_worker_spec.rb +++ b/spec/workers/object_pool/destroy_worker_spec.rb @@ -16,9 +16,13 @@ RSpec.describe ObjectPool::DestroyWorker, feature_category: :shared do subject { described_class.new } it 'requests Gitaly to remove the object pool' do - expect(Gitlab::GitalyClient).to receive(:call) - .with(pool.shard_name, :object_pool_service, :delete_object_pool, - Object, timeout: Gitlab::GitalyClient.long_timeout) + expect(Gitlab::GitalyClient).to receive(:call).with( + pool.shard_name, + :object_pool_service, + :delete_object_pool, + Object, + timeout: Gitlab::GitalyClient.long_timeout + ) subject.perform(pool.id) end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index a8b0f91bf7d..7a85038d946 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -37,7 +37,5 @@ RSpec.describe PipelineHooksWorker, feature_category: :continuous_integration do end end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed end diff --git a/spec/workers/pipeline_metrics_worker_spec.rb b/spec/workers/pipeline_metrics_worker_spec.rb index f7b397d91a6..7bd98f8f55d 100644 --- a/spec/workers/pipeline_metrics_worker_spec.rb +++ b/spec/workers/pipeline_metrics_worker_spec.rb @@ -6,19 +6,19 @@ RSpec.describe PipelineMetricsWorker, feature_category: :continuous_integration let(:project) { create(:project, :repository) } let!(:merge_request) do - create(:merge_request, source_project: project, - source_branch: pipeline.ref, - head_pipeline: pipeline) + create(:merge_request, source_project: project, source_branch: pipeline.ref, head_pipeline: pipeline) end let(:pipeline) do - create(:ci_empty_pipeline, - status: status, - project: project, - ref: 'master', - sha: project.repository.commit('master').id, - started_at: 1.hour.ago, - finished_at: Time.current) + create( + :ci_empty_pipeline, + status: status, + project: project, + ref: 'master', + sha: project.repository.commit('master').id, + started_at: 1.hour.ago, + finished_at: Time.current + ) end let(:status) { 'pending' } diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index 1fc77c42cbc..c95119b0d02 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -82,11 +82,13 @@ RSpec.describe ProcessCommitWorker, feature_category: :source_code_management do context 'when commit is a merge request merge commit to the default branch' do let(:merge_request) do - create(:merge_request, - description: "Closes #{issue.to_reference}", - source_branch: 'feature-merged', - target_branch: 'master', - source_project: project) + create( + :merge_request, + description: "Closes #{issue.to_reference}", + source_branch: 'feature-merged', + target_branch: 'master', + source_project: project + ) end let(:commit) do diff --git a/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb b/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb index 15234827efa..68af5e61e3b 100644 --- a/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb +++ b/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb @@ -92,8 +92,11 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker, feature_category: : it 'invokes Projects::InactiveProjectsDeletionNotificationWorker for inactive projects' do Gitlab::Redis::SharedState.with do |redis| - expect(redis).to receive(:hset).with('inactive_projects_deletion_warning_email_notified', - "project:#{inactive_large_project.id}", Date.current) + expect(redis).to receive(:hset).with( + 'inactive_projects_deletion_warning_email_notified', + "project:#{inactive_large_project.id}", + Date.current + ) end expect(::Projects::InactiveProjectsDeletionNotificationWorker).to receive(:perform_async).with( inactive_large_project.id, deletion_date).and_call_original @@ -104,8 +107,11 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker, feature_category: : it 'does not invoke InactiveProjectsDeletionNotificationWorker for already notified inactive projects' do Gitlab::Redis::SharedState.with do |redis| - redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}", - Date.current.to_s) + redis.hset( + 'inactive_projects_deletion_warning_email_notified', + "project:#{inactive_large_project.id}", + Date.current.to_s + ) end expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async) @@ -116,8 +122,11 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker, feature_category: : it 'invokes Projects::DestroyService for projects that are inactive even after being notified' do Gitlab::Redis::SharedState.with do |redis| - redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}", - 15.months.ago.to_date.to_s) + redis.hset( + 'inactive_projects_deletion_warning_email_notified', + "project:#{inactive_large_project.id}", + 15.months.ago.to_date.to_s + ) end expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async) @@ -129,8 +138,9 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker, feature_category: : expect(inactive_large_project.reload.pending_delete).to eq(true) Gitlab::Redis::SharedState.with do |redis| - expect(redis.hget('inactive_projects_deletion_warning_email_notified', - "project:#{inactive_large_project.id}")).to be_nil + expect( + redis.hget('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}") + ).to be_nil end end diff --git a/spec/workers/projects/inactive_projects_deletion_notification_worker_spec.rb b/spec/workers/projects/inactive_projects_deletion_notification_worker_spec.rb index 28668188497..2ac2b5d0795 100644 --- a/spec/workers/projects/inactive_projects_deletion_notification_worker_spec.rb +++ b/spec/workers/projects/inactive_projects_deletion_notification_worker_spec.rb @@ -22,14 +22,15 @@ RSpec.describe Projects::InactiveProjectsDeletionNotificationWorker, feature_cat worker.perform(project.id, deletion_date) Gitlab::Redis::SharedState.with do |redis| - expect(redis.hget('inactive_projects_deletion_warning_email_notified', - "project:#{project.id}")).to eq(Date.current.to_s) + expect( + redis.hget('inactive_projects_deletion_warning_email_notified', "project:#{project.id}") + ).to eq(Date.current.to_s) end end it 'rescues and logs the exception if project does not exist' do - expect(Gitlab::ErrorTracking).to receive(:log_exception).with(instance_of(ActiveRecord::RecordNotFound), - { project_id: non_existing_project_id }) + expect(Gitlab::ErrorTracking).to receive(:log_exception) + .with(instance_of(ActiveRecord::RecordNotFound), { project_id: non_existing_project_id }) worker.perform(non_existing_project_id, deletion_date) end diff --git a/spec/workers/rebase_worker_spec.rb b/spec/workers/rebase_worker_spec.rb index eec221094e6..ee8fd8b7461 100644 --- a/spec/workers/rebase_worker_spec.rb +++ b/spec/workers/rebase_worker_spec.rb @@ -10,11 +10,13 @@ RSpec.describe RebaseWorker, '#perform', feature_category: :source_code_manageme let(:forked_project) { fork_project(upstream_project, nil, repository: true) } let(:merge_request) do - create(:merge_request, - source_project: forked_project, - source_branch: 'feature_conflict', - target_project: upstream_project, - target_branch: 'master') + create( + :merge_request, + source_project: forked_project, + source_branch: 'feature_conflict', + target_project: upstream_project, + target_branch: 'master' + ) end it 'sets the correct project for running hooks' do diff --git a/spec/workers/remote_mirror_notification_worker_spec.rb b/spec/workers/remote_mirror_notification_worker_spec.rb index 46f44d0047b..e7c32d79457 100644 --- a/spec/workers/remote_mirror_notification_worker_spec.rb +++ b/spec/workers/remote_mirror_notification_worker_spec.rb @@ -30,8 +30,10 @@ RSpec.describe RemoteMirrorNotificationWorker, :mailer, feature_category: :sourc end it 'does nothing when a notification has already been sent' do - mirror.update_columns(last_error: "There was a problem fetching", - error_notification_sent: true) + mirror.update_columns( + last_error: "There was a problem fetching", + error_notification_sent: true + ) expect(NotificationService).not_to receive(:new) diff --git a/spec/workers/remove_expired_members_worker_spec.rb b/spec/workers/remove_expired_members_worker_spec.rb index 354ce3fc9b4..f77a078750d 100644 --- a/spec/workers/remove_expired_members_worker_spec.rb +++ b/spec/workers/remove_expired_members_worker_spec.rb @@ -35,8 +35,10 @@ RSpec.describe RemoveExpiredMembersWorker, feature_category: :system_access do new_job = Sidekiq::Worker.jobs.last - expect(new_job).to include('meta.project' => expired_project_member.project.full_path, - 'meta.user' => expired_project_member.user.username) + expect(new_job).to include( + 'meta.project' => expired_project_member.project.full_path, + 'meta.user' => expired_project_member.user.username + ) end end @@ -60,8 +62,7 @@ RSpec.describe RemoveExpiredMembersWorker, feature_category: :system_access do worker.perform expect( - Users::GhostUserMigration.where(user: expired_project_bot, - initiator_user: nil) + Users::GhostUserMigration.where(user: expired_project_bot, initiator_user: nil) ).to be_exists end end @@ -116,8 +117,10 @@ RSpec.describe RemoveExpiredMembersWorker, feature_category: :system_access do new_job = Sidekiq::Worker.jobs.last - expect(new_job).to include('meta.root_namespace' => expired_group_member.group.full_path, - 'meta.user' => expired_group_member.user.username) + expect(new_job).to include( + 'meta.root_namespace' => expired_group_member.group.full_path, + 'meta.user' => expired_group_member.user.username + ) end end diff --git a/spec/workers/remove_unaccepted_member_invites_worker_spec.rb b/spec/workers/remove_unaccepted_member_invites_worker_spec.rb index 97ddf9223b3..5173967c57a 100644 --- a/spec/workers/remove_unaccepted_member_invites_worker_spec.rb +++ b/spec/workers/remove_unaccepted_member_invites_worker_spec.rb @@ -13,15 +13,19 @@ RSpec.describe RemoveUnacceptedMemberInvitesWorker, feature_category: :system_ac it 'removes unaccepted members', :aggregate_failures do unaccepted_group_invitee = create( - :group_member, invite_token: 't0ken', - invite_email: 'group_invitee@example.com', - user: nil, - created_at: Time.current - 5.days) + :group_member, + invite_token: 't0ken', + invite_email: 'group_invitee@example.com', + user: nil, + created_at: Time.current - 5.days + ) unaccepted_project_invitee = create( - :project_member, invite_token: 't0ken', - invite_email: 'project_invitee@example.com', - user: nil, - created_at: Time.current - 5.days) + :project_member, + invite_token: 't0ken', + invite_email: 'project_invitee@example.com', + user: nil, + created_at: Time.current - 5.days + ) expect { worker.perform }.to change { Member.count }.by(-2) @@ -33,13 +37,17 @@ RSpec.describe RemoveUnacceptedMemberInvitesWorker, feature_category: :system_ac context 'invited members still within expiration threshold' do it 'leaves invited members', :aggregate_failures do group_invitee = create( - :group_member, invite_token: 't0ken', - invite_email: 'group_invitee@example.com', - user: nil) + :group_member, + invite_token: 't0ken', + invite_email: 'group_invitee@example.com', + user: nil + ) project_invitee = create( - :project_member, invite_token: 't0ken', - invite_email: 'project_invitee@example.com', - user: nil) + :project_member, + invite_token: 't0ken', + invite_email: 'project_invitee@example.com', + user: nil + ) expect { worker.perform }.not_to change { Member.count } @@ -56,15 +64,19 @@ RSpec.describe RemoveUnacceptedMemberInvitesWorker, feature_category: :system_ac it 'leaves accepted members', :aggregate_failures do user = create(:user) accepted_group_invitee = create( - :group_member, invite_token: 't0ken', - invite_email: 'group_invitee@example.com', - user: user, - created_at: Time.current - 5.days) + :group_member, + invite_token: 't0ken', + invite_email: 'group_invitee@example.com', + user: user, + created_at: Time.current - 5.days + ) accepted_project_invitee = create( - :project_member, invite_token: nil, - invite_email: 'project_invitee@example.com', - user: user, - created_at: Time.current - 5.days) + :project_member, + invite_token: nil, + invite_email: 'project_invitee@example.com', + user: user, + created_at: Time.current - 5.days + ) expect { worker.perform }.not_to change { Member.count } diff --git a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb index 56dc3511cfc..e5564834443 100644 --- a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb +++ b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb @@ -13,24 +13,16 @@ RSpec.describe RemoveUnreferencedLfsObjectsWorker, feature_category: :source_cod let!(:referenced_lfs_object1) { create(:lfs_object, oid: '3' * 64) } let!(:referenced_lfs_object2) { create(:lfs_object, oid: '4' * 64) } let!(:lfs_objects_project1_1) do - create(:lfs_objects_project, - project: project1, - lfs_object: referenced_lfs_object1 + create(:lfs_objects_project, project: project1, lfs_object: referenced_lfs_object1 ) end let!(:lfs_objects_project2_1) do - create(:lfs_objects_project, - project: project2, - lfs_object: referenced_lfs_object1 - ) + create(:lfs_objects_project, project: project2, lfs_object: referenced_lfs_object1) end let!(:lfs_objects_project1_2) do - create(:lfs_objects_project, - project: project1, - lfs_object: referenced_lfs_object2 - ) + create(:lfs_objects_project, project: project1, lfs_object: referenced_lfs_object2) end it 'removes unreferenced lfs objects' do diff --git a/spec/workers/repository_update_remote_mirror_worker_spec.rb b/spec/workers/repository_update_remote_mirror_worker_spec.rb index c1987658b0d..61b9441ec27 100644 --- a/spec/workers/repository_update_remote_mirror_worker_spec.rb +++ b/spec/workers/repository_update_remote_mirror_worker_spec.rb @@ -57,14 +57,16 @@ RSpec.describe RepositoryUpdateRemoteMirrorWorker, :clean_gitlab_redis_shared_st end it 'retries 3 times for the worker to finish before rescheduling' do - expect(subject).to receive(:in_lock) - .with("#{described_class.name}:#{remote_mirror.id}", - retries: 3, - ttl: remote_mirror.max_runtime, - sleep_sec: described_class::LOCK_WAIT_TIME) - .and_raise(Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError) - expect(described_class).to receive(:perform_in) - .with(remote_mirror.backoff_delay, remote_mirror.id, scheduled_time, 0) + expect(subject).to receive(:in_lock).with( + "#{described_class.name}:#{remote_mirror.id}", + retries: 3, + ttl: remote_mirror.max_runtime, + sleep_sec: described_class::LOCK_WAIT_TIME + ).and_raise(Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError) + + expect(described_class) + .to receive(:perform_in) + .with(remote_mirror.backoff_delay, remote_mirror.id, scheduled_time, 0) subject.perform(remote_mirror.id, scheduled_time) end diff --git a/spec/workers/run_pipeline_schedule_worker_spec.rb b/spec/workers/run_pipeline_schedule_worker_spec.rb index 75938d3b793..d0e4de1aa98 100644 --- a/spec/workers/run_pipeline_schedule_worker_spec.rb +++ b/spec/workers/run_pipeline_schedule_worker_spec.rb @@ -137,9 +137,11 @@ RSpec.describe RunPipelineScheduleWorker, feature_category: :continuous_integrat expect(Gitlab::ErrorTracking) .to receive(:track_and_raise_for_dev_exception) - .with(ActiveRecord::StatementInvalid, - issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/41231', - schedule_id: pipeline_schedule.id).once + .with( + ActiveRecord::StatementInvalid, + issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/41231', + schedule_id: pipeline_schedule.id + ).once end it 'increments Prometheus counter' do diff --git a/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb b/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb index 5eae275be36..c64a597833d 100644 --- a/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb +++ b/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb @@ -66,11 +66,13 @@ RSpec.describe UpdateHeadPipelineForMergeRequestWorker, feature_category: :conti context 'when a merge request pipeline exists' do let_it_be(:merge_request_pipeline) do - create(:ci_pipeline, - project: project, - source: :merge_request_event, - sha: latest_sha, - merge_request: merge_request) + create( + :ci_pipeline, + project: project, + source: :merge_request_event, + sha: latest_sha, + merge_request: merge_request + ) end it 'sets the merge request pipeline as the head pipeline' do diff --git a/spec/workers/web_hook_worker_spec.rb b/spec/workers/web_hook_worker_spec.rb index e39017c4ccf..be43b83ec0a 100644 --- a/spec/workers/web_hook_worker_spec.rb +++ b/spec/workers/web_hook_worker_spec.rb @@ -28,8 +28,6 @@ RSpec.describe WebHookWorker, feature_category: :integrations do .to change { Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid }.to(uuid) end - it_behaves_like 'worker with data consistency', - described_class, - data_consistency: :delayed + it_behaves_like 'worker with data consistency', described_class, data_consistency: :delayed end end |