diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-08 03:07:09 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-08 03:07:09 +0300 |
commit | 044a953eb6b92e39cf32678296aa219176c9ad92 (patch) | |
tree | 01dafcb0cd46816b6aec864aed791c521c999a45 | |
parent | 23d78a2bf594e74fef0a9330d7a26bd9398ae4b9 (diff) |
Add latest changes from gitlab-org/gitlab@master
66 files changed, 362 insertions, 502 deletions
diff --git a/.rubocop_todo/layout/empty_line_between_defs.yml b/.rubocop_todo/layout/empty_line_between_defs.yml deleted file mode 100644 index 2b0a00b420f..00000000000 --- a/.rubocop_todo/layout/empty_line_between_defs.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -# Cop supports --autocorrect. -Layout/EmptyLineBetweenDefs: - Exclude: - - 'db/post_migrate/20220202105733_delete_service_template_records.rb' - - 'ee/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column.rb' - - 'lib/gitlab/import_export/remote_stream_upload.rb' - - 'lib/gitlab/redis/multi_store.rb' diff --git a/.rubocop_todo/style/redundant_regexp_escape.yml b/.rubocop_todo/style/redundant_regexp_escape.yml index 9da348f849d..22608a8e1f5 100644 --- a/.rubocop_todo/style/redundant_regexp_escape.yml +++ b/.rubocop_todo/style/redundant_regexp_escape.yml @@ -79,33 +79,3 @@ Style/RedundantRegexpEscape: - 'qa/spec/runtime/key/rsa_spec.rb' - 'scripts/qa/testcases-check' - 'scripts/setup/find-jh-branch.rb' - - 'spec/controllers/projects_controller_spec.rb' - - 'spec/features/read_only_spec.rb' - - 'spec/helpers/tab_helper_spec.rb' - - 'spec/lib/banzai/filter/references/reference_filter_spec.rb' - - 'spec/lib/banzai/filter/syntax_highlight_filter_spec.rb' - - 'spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb' - - 'spec/lib/gitlab/ci/config_spec.rb' - - 'spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb' - - 'spec/lib/gitlab/import_export/saver_spec.rb' - - 'spec/lib/gitlab/kubernetes/kube_client_spec.rb' - - 'spec/lib/gitlab/sql/pattern_spec.rb' - - 'spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb' - - 'spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb' - - 'spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb' - - 'spec/mailers/emails/profile_spec.rb' - - 'spec/models/release_highlight_spec.rb' - - 'spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb' - - 'spec/requests/api/graphql_spec.rb' - - 'spec/requests/api/project_debian_distributions_spec.rb' - - 'spec/requests/api/repositories_spec.rb' - - 'spec/services/projects/download_service_spec.rb' - - 'spec/support/matchers/exceed_query_limit.rb' - - 'spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb' - - 'spec/support/shared_examples/mailers/notify_shared_examples.rb' - - 'spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb' - - 'spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb' - - 'spec/uploaders/personal_file_uploader_spec.rb' - - 'spec/views/help/index.html.haml_spec.rb' - - 'tooling/danger/project_helper.rb' diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue index 1b7d5af6134..56d2ff86fb7 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue @@ -1,11 +1,7 @@ <script> import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui'; -import { - ALERT_MESSAGES, - ADMIN_GARBAGE_COLLECTION_TIP, - ALERT_DANGER_IMPORTING, -} from '../../constants/index'; +import { ALERT_MESSAGES, ADMIN_GARBAGE_COLLECTION_TIP } from '../../constants/index'; export default { components: { @@ -27,7 +23,6 @@ export default { }, }, garbageCollectionHelpPagePath: { type: String, required: false, default: '' }, - containerRegistryImportingHelpPagePath: { type: String, required: false, default: '' }, isAdmin: { type: Boolean, default: false, @@ -53,11 +48,6 @@ export default { } return config; }, - alertHref() { - return this.deleteAlertType === ALERT_DANGER_IMPORTING - ? this.containerRegistryImportingHelpPagePath - : this.garbageCollectionHelpPagePath; - }, }, }; </script> @@ -71,7 +61,7 @@ export default { > <gl-sprintf :message="deleteAlertConfig.message"> <template #docLink="{ content }"> - <gl-link :href="alertHref" target="_blank"> + <gl-link :href="garbageCollectionHelpPagePath" target="_blank"> {{ content }} </gl-link> </template> diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js index 98c24350f09..7bb69363743 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js @@ -93,10 +93,6 @@ export const DETAILS_DELETE_IMAGE_ERROR_MESSAGE = s__( 'ContainerRegistry|Something went wrong while scheduling the image for deletion.', ); -export const DETAILS_IMPORTING_ERROR_MESSAGE = s__( - 'ContainerRegistry|Tags temporarily cannot be marked for deletion. Please try again in a few minutes. %{docLinkStart}More details%{docLinkEnd}.', -); - export const DELETE_IMAGE_CONFIRMATION_TITLE = s__('ContainerRegistry|Delete image repository?'); export const DELETE_IMAGE_CONFIRMATION_TEXT = s__( 'ContainerRegistry|Deleting the image repository will delete all images and tags inside. This action cannot be undone. Please type the following to confirm: %{code}', @@ -137,7 +133,6 @@ export const ALERT_DANGER_TAG = 'danger_tag'; export const ALERT_SUCCESS_TAGS = 'success_tags'; export const ALERT_DANGER_TAGS = 'danger_tags'; export const ALERT_DANGER_IMAGE = 'danger_image'; -export const ALERT_DANGER_IMPORTING = 'danger_importing'; export const DELETE_SCHEDULED = 'DELETE_SCHEDULED'; export const DELETE_FAILED = 'DELETE_FAILED'; @@ -148,7 +143,6 @@ export const ALERT_MESSAGES = { [ALERT_SUCCESS_TAGS]: DELETE_TAGS_SUCCESS_MESSAGE, [ALERT_DANGER_TAGS]: DELETE_TAGS_ERROR_MESSAGE, [ALERT_DANGER_IMAGE]: DETAILS_DELETE_IMAGE_ERROR_MESSAGE, - [ALERT_DANGER_IMPORTING]: DETAILS_IMPORTING_ERROR_MESSAGE, }; export const UNFINISHED_STATUS = 'UNFINISHED'; diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue index b339c8c8371..83c0d2cdfca 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue @@ -20,7 +20,6 @@ import { ALERT_SUCCESS_TAGS, ALERT_DANGER_TAGS, ALERT_DANGER_IMAGE, - ALERT_DANGER_IMPORTING, FETCH_IMAGES_LIST_ERROR_MESSAGE, UNFINISHED_STATUS, MISSING_OR_DELETED_IMAGE_BREADCRUMB, @@ -33,8 +32,6 @@ import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_repository_tags.query.graphql'; import getContainerRepositoriesDetails from '../graphql/queries/get_container_repositories_details.query.graphql'; -const REPOSITORY_IMPORTING_ERROR_MESSAGE = 'repository importing'; - export default { name: 'RegistryDetailsPage', components: { @@ -157,17 +154,12 @@ export default { }); if (data?.destroyContainerRepositoryTags?.errors[0]) { - throw new Error(data.destroyContainerRepositoryTags.errors[0]); + throw new Error(); } this.deleteAlertType = itemsToBeDeleted.length === 0 ? ALERT_SUCCESS_TAG : ALERT_SUCCESS_TAGS; } catch (e) { - if (e.message === REPOSITORY_IMPORTING_ERROR_MESSAGE) { - this.deleteAlertType = ALERT_DANGER_IMPORTING; - } else { - this.deleteAlertType = - itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS; - } + this.deleteAlertType = itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS; } this.mutationLoading = false; @@ -203,7 +195,6 @@ export default { <delete-alert v-model="deleteAlertType" :garbage-collection-help-page-path="config.garbageCollectionHelpPagePath" - :container-registry-importing-help-page-path="config.containerRegistryImportingHelpPagePath" :is-admin="config.isAdmin" class="gl-my-2" /> diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb index a85875b8983..aa0838752e2 100644 --- a/app/controllers/projects/network_controller.rb +++ b/app/controllers/projects/network_controller.rb @@ -14,7 +14,13 @@ class Projects::NetworkController < Projects::ApplicationController urgency :low, [:show] def show - @url = project_network_path(@project, @ref, @options.merge(format: :json)) + @url = if Feature.enabled?(:use_ref_type_parameter, @project) + project_network_path(@project, @ref, @options.merge(format: :json, ref_type: ref_type)) + else + project_network_path(@project, @ref, @options.merge(format: :json)) + end + + @ref_type = ref_type @commit_url = project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s") respond_to do |format| diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index 31a0935cf96..8ac6d872aae 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -24,7 +24,11 @@ class Projects::RefsController < Projects::ApplicationController when "blob" project_blob_path(@project, @id) when "graph" - project_network_path(@project, @id, @options) + if Feature.enabled?(:use_ref_type_parameter, @project) + project_network_path(@project, @id, ref_type: ref_type) + else + project_network_path(@project, @id, @options) + end when "graphs" if Feature.enabled?(:use_ref_type_parameter, @project) project_graph_path(@project, @id, ref_type: ref_type) diff --git a/app/models/ci/group_variable.rb b/app/models/ci/group_variable.rb index 508aaa5a63c..b03c46a164f 100644 --- a/app/models/ci/group_variable.rb +++ b/app/models/ci/group_variable.rb @@ -3,9 +3,11 @@ module Ci class GroupVariable < Ci::ApplicationRecord include Ci::HasVariable - include Presentable include Ci::Maskable include Ci::RawVariable + include Limitable + include Presentable + prepend HasEnvironmentScope belongs_to :group, class_name: "::Group" @@ -21,6 +23,9 @@ module Ci scope :by_environment_scope, -> (environment_scope) { where(environment_scope: environment_scope) } scope :for_groups, ->(group_ids) { where(group_id: group_ids) } + self.limit_name = 'group_ci_variables' + self.limit_scope = :group + def audit_details key end diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb index f4e17b5d812..23fe89c38df 100644 --- a/app/models/ci/variable.rb +++ b/app/models/ci/variable.rb @@ -3,9 +3,11 @@ module Ci class Variable < Ci::ApplicationRecord include Ci::HasVariable - include Presentable include Ci::Maskable include Ci::RawVariable + include Limitable + include Presentable + prepend HasEnvironmentScope belongs_to :project @@ -20,6 +22,9 @@ module Ci scope :unprotected, -> { where(protected: false) } scope :by_environment_scope, -> (environment_scope) { where(environment_scope: environment_scope) } + self.limit_name = 'project_ci_variables' + self.limit_scope = :project + def audit_details key end diff --git a/app/models/operations/feature_flags_client.rb b/app/models/operations/feature_flags_client.rb index e8c237abbc5..5a05d76254d 100644 --- a/app/models/operations/feature_flags_client.rb +++ b/app/models/operations/feature_flags_client.rb @@ -19,11 +19,11 @@ module Operations before_validation :ensure_token! - def self.find_for_project_and_token(project, token) - return unless project + def self.find_for_project_and_token(project_id, token) + return unless project_id return unless token - where(project_id: project).find_by_token(token) + where(project_id: project_id).find_by_token(token) end def self.update_last_feature_flag_updated_at!(project) diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml index 6060d697f52..f6d05959d2e 100644 --- a/app/views/groups/registry/repositories/index.html.haml +++ b/app/views/groups/registry/repositories/index.html.haml @@ -12,7 +12,6 @@ "registry_host_url_with_port" => escape_once(registry_config.host_port), "garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'), "run_cleanup_policies_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'run-the-cleanup-policy-now'), - "container_registry_importing_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion'), "is_admin": current_user&.admin.to_s, is_group_page: "true", "group_path": @group.full_path, diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index 2a3171e9fd8..06123aea960 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -1,10 +1,11 @@ - breadcrumb_title _("Graph") - page_title _("Graph"), @ref +- network_path = Feature.enabled?(:use_ref_type_parameter) ? project_network_path(@project, @id, ref_type: @ref_type ) : project_network_path(@project, @id) = render "head" .gl-mt-5 .project-network.gl-border-1.gl-border-solid.gl-border-gray-300 .controls.gl-bg-gray-50.gl-p-2.gl-font-base.gl-text-gray-400.gl-border-b-1.gl-border-b-solid.gl-border-b-gray-300 - = form_tag project_network_path(@project, @id), method: :get, class: 'form-inline network-form' do |f| + = form_tag network_path, method: :get, class: 'form-inline network-form' do |f| = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: _("Git revision"), class: 'search-input form-control gl-form-input input-mx-250 search-sha gl-mr-2' = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, icon: 'search') .inline.gl-ml-5 diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml index 51f0b6319a1..59b7b6ca334 100644 --- a/app/views/projects/registry/repositories/index.html.haml +++ b/app/views/projects/registry/repositories/index.html.haml @@ -15,7 +15,6 @@ "expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'cleanup-policy'), "garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'), "run_cleanup_policies_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'run-the-cleanup-policy-now'), - "container_registry_importing_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion'), "project_path": @project.full_path, "gid_prefix": container_repository_gid_prefix, "is_admin": current_user&.admin.to_s, diff --git a/db/post_migrate/20220202105733_delete_service_template_records.rb b/db/post_migrate/20220202105733_delete_service_template_records.rb index b70bacc83aa..e1697f23588 100644 --- a/db/post_migrate/20220202105733_delete_service_template_records.rb +++ b/db/post_migrate/20220202105733_delete_service_template_records.rb @@ -5,6 +5,7 @@ class DeleteServiceTemplateRecords < Gitlab::Database::Migration[1.0] # Disable single-table inheritance self.inheritance_column = :_type_disabled end + def up Integration.where(template: true).delete_all end diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md index 9ddb1bb51e2..e86f9ff4673 100644 --- a/doc/user/application_security/vulnerabilities/index.md +++ b/doc/user/application_security/vulnerabilities/index.md @@ -59,6 +59,8 @@ To change a vulnerability's status from its Vulnerability Page: 1. From the **Status** dropdown list select a status, then select **Change status**. 1. Optionally, at the bottom of the page, add a comment to the log entry. +The Actions log records each status change along with which user changed the status and the time of the change. + ## Creating an issue for a vulnerability From a vulnerability's page you can create an issue to track all action taken to resolve or diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md index 8ebef752bc9..ced4a78faaa 100644 --- a/doc/user/packages/container_registry/index.md +++ b/doc/user/packages/container_registry/index.md @@ -705,13 +705,6 @@ There may be some errors not properly cached. Follow these steps to investigate Follow [this issue](https://gitlab.com/gitlab-org/container-registry/-/issues/551) for details. -### Tags temporarily cannot be marked for deletion - -GitLab is [migrating to the next generation of the Container Registry](https://gitlab.com/groups/gitlab-org/-/epics/5523). -During the migration, you may encounter difficulty deleting tags. -If you encounter an error, it's likely that your image repository is in the process of being migrated. -Wait a few minutes and try again. - ### `unauthorized: authentication required` when pushing large images When pushing large images, you might get an error like the following: diff --git a/lib/api/unleash.rb b/lib/api/unleash.rb index 38ce4bd7f32..b2133dc743a 100644 --- a/lib/api/unleash.rb +++ b/lib/api/unleash.rb @@ -63,13 +63,9 @@ module API cache_context: -> (client) { client.unleash_api_cache_key } end - def project - @project ||= find_project(params[:project_id]) - end - def feature_flags_client strong_memoize(:feature_flags_client) do - client = Operations::FeatureFlagsClient.find_for_project_and_token(project, unleash_instance_id) + client = Operations::FeatureFlagsClient.find_for_project_and_token(params[:project_id], unleash_instance_id) client.unleash_app_name = unleash_app_name if client client end @@ -86,12 +82,6 @@ module API def authorize_by_unleash_instance_id! unauthorized! unless feature_flags_client end - - def feature_flags - return [] unless unleash_app_name.present? - - Operations::FeatureFlag.for_unleash_client(project, unleash_app_name) - end end end end diff --git a/lib/gitlab/import_export/remote_stream_upload.rb b/lib/gitlab/import_export/remote_stream_upload.rb index f3bd241c0bd..1fb3faf0767 100644 --- a/lib/gitlab/import_export/remote_stream_upload.rb +++ b/lib/gitlab/import_export/remote_stream_upload.rb @@ -25,6 +25,7 @@ module Gitlab end end end + class StreamError < StandardError attr_reader :response_body @@ -33,6 +34,7 @@ module Gitlab @response_body = response_body end end + class ChunkStream DEFAULT_BUFFER_SIZE = 128.kilobytes diff --git a/lib/gitlab/redis/multi_store.rb b/lib/gitlab/redis/multi_store.rb index 12cb1fc6153..4f58bee49d0 100644 --- a/lib/gitlab/redis/multi_store.rb +++ b/lib/gitlab/redis/multi_store.rb @@ -10,6 +10,7 @@ module Gitlab 'Value not found on the redis primary store. Read from the redis secondary store successful.' end end + class PipelinedDiffError < StandardError def initialize(result_primary, result_secondary) @result_primary = result_primary @@ -22,6 +23,7 @@ module Gitlab "Result from the secondary: #{@result_secondary.inspect}." end end + class MethodMissingError < StandardError def message 'Method missing. Falling back to execute method on the redis secondary store.' diff --git a/lib/sidebars/projects/menus/repository_menu.rb b/lib/sidebars/projects/menus/repository_menu.rb index 10eb9d9d22d..735be5a5133 100644 --- a/lib/sidebars/projects/menus/repository_menu.rb +++ b/lib/sidebars/projects/menus/repository_menu.rb @@ -108,9 +108,15 @@ module Sidebars end def graphs_menu_item + link = if Feature.enabled?(:use_ref_type_parameter, context.project) + project_network_path(context.project, context.current_ref, ref_type: ref_type_from_context(context)) + else + project_network_path(context.project, context.current_ref) + end + ::Sidebars::MenuItem.new( title: _('Graph'), - link: project_network_path(context.project, context.current_ref), + link: link, active_routes: { controller: :network }, item_id: :graphs ) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 0aa1687aa90..b74c23290c2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -10737,9 +10737,6 @@ msgstr "" msgid "ContainerRegistry|Tags successfully marked for deletion." msgstr "" -msgid "ContainerRegistry|Tags temporarily cannot be marked for deletion. Please try again in a few minutes. %{docLinkStart}More details%{docLinkEnd}." -msgstr "" - msgid "ContainerRegistry|Tags that match these rules are %{strongStart}kept%{strongEnd}, even if they match a removal rule below. The %{secondStrongStart}latest%{secondStrongEnd} tag is always kept." msgstr "" diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb index e81193a92a3..a7a8361ae20 100644 --- a/spec/controllers/projects/refs_controller_spec.rb +++ b/spec/controllers/projects/refs_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::RefsController do +RSpec.describe Projects::RefsController, feature_category: :source_code_management do let_it_be(:project) { create(:project, :repository) } let(:user) { create(:user) } @@ -15,7 +15,6 @@ RSpec.describe Projects::RefsController do using RSpec::Parameterized::TableSyntax let(:id) { 'master' } - let(:params) do { destination: destination, namespace_id: project.namespace.to_param, project_id: project, id: id, ref_type: ref_type } @@ -50,7 +49,7 @@ RSpec.describe Projects::RefsController do end with_them do - it 'redirects to commits' do + it 'redirects to destination' do expect(subject).to redirect_to(redirected_to) end end @@ -63,7 +62,7 @@ RSpec.describe Projects::RefsController do 'blob' | nil | lazy { project_blob_path(project, id) } 'blob' | 'heads' | lazy { project_blob_path(project, id) } 'graph' | nil | lazy { project_network_path(project, id) } - 'graph' | 'heads' | lazy { project_network_path(project, id) } + 'graph' | 'heads' | lazy { project_network_path(project, id, ref_type: 'heads') } 'graphs' | nil | lazy { project_graph_path(project, id) } 'graphs' | 'heads' | lazy { project_graph_path(project, id, ref_type: 'heads') } 'find_file' | nil | lazy { project_find_file_path(project, id) } @@ -79,7 +78,7 @@ RSpec.describe Projects::RefsController do end with_them do - it 'redirects to commits' do + it 'redirects to destination' do expect(subject).to redirect_to(redirected_to) end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index f80feed6c33..fdca05e3517 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -1326,7 +1326,7 @@ RSpec.describe ProjectsController do text: merge_request.to_reference } - expect(json_response['body']).to match(/\!#{merge_request.iid} \(closed\)/) + expect(json_response['body']).to match(/!#{merge_request.iid} \(closed\)/) end end diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb index dbb321d343f..11f94967aaf 100644 --- a/spec/features/groups/container_registry_spec.rb +++ b/spec/features/groups/container_registry_spec.rb @@ -97,8 +97,6 @@ RSpec.describe 'Container Registry', :js, feature_category: :container_registry expect(find('.modal .modal-title')).to have_content _('Remove tag') find('.modal .modal-footer .btn-danger').click end - - it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['latest'] end end diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb index bdf0f27b5b3..98cf024afa8 100644 --- a/spec/features/projects/container_registry_spec.rb +++ b/spec/features/projects/container_registry_spec.rb @@ -104,8 +104,6 @@ RSpec.describe 'Container Registry', :js, feature_category: :projects do find('.modal .modal-footer .btn-danger').click end - it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['1'] - it('pagination navigate to the second page') do visit_next_page diff --git a/spec/features/read_only_spec.rb b/spec/features/read_only_spec.rb index 18182b675df..e65727c05e3 100644 --- a/spec/features/read_only_spec.rb +++ b/spec/features/read_only_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'read-only message', feature_category: :database do allow(Gitlab::Database).to receive(:read_only?).and_return(true) end - it_behaves_like 'Read-only instance', /You are on a read\-only GitLab instance./ + it_behaves_like 'Read-only instance', /You are on a read-only GitLab instance./ end context 'when database is in read-write mode' do @@ -22,6 +22,6 @@ RSpec.describe 'read-only message', feature_category: :database do allow(Gitlab::Database).to receive(:read_only?).and_return(false) end - it_behaves_like 'Read-write instance', /You are on a read\-only GitLab instance./ + it_behaves_like 'Read-write instance', /You are on a read-only GitLab instance./ end end diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js index 4a026f35822..d45b993b5a2 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js @@ -6,7 +6,6 @@ import { DELETE_TAG_ERROR_MESSAGE, DELETE_TAGS_SUCCESS_MESSAGE, DELETE_TAGS_ERROR_MESSAGE, - DETAILS_IMPORTING_ERROR_MESSAGE, ADMIN_GARBAGE_COLLECTION_TIP, } from '~/packages_and_registries/container_registry/explorer/constants'; @@ -77,7 +76,6 @@ describe('Delete alert', () => { }); }); }); - describe('error states', () => { describe.each` deleteAlertType | message @@ -107,25 +105,6 @@ describe('Delete alert', () => { }); }); - describe('importing repository error state', () => { - beforeEach(() => { - mountComponent({ - deleteAlertType: 'danger_importing', - containerRegistryImportingHelpPagePath: 'https://foobar', - }); - }); - - it('alert exist and text is appropriate', () => { - expect(findAlert().text()).toMatchInterpolatedText(DETAILS_IMPORTING_ERROR_MESSAGE); - }); - - it('alert body contains link', () => { - const alertLink = findLink(); - expect(alertLink.exists()).toBe(true); - expect(alertLink.attributes('href')).toBe('https://foobar'); - }); - }); - describe('dismissing alert', () => { it('GlAlert dismiss event triggers a change event', () => { mountComponent({ deleteAlertType: 'success_tags' }); diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js index b11048cd7a2..e5b99f15e8c 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js @@ -249,15 +249,6 @@ export const graphQLDeleteImageRepositoryTagsMock = { }, }; -export const graphQLDeleteImageRepositoryTagImportingErrorMock = { - data: { - destroyContainerRepositoryTags: { - errors: ['repository importing'], - __typename: 'DestroyContainerRepositoryTagsPayload', - }, - }, -}; - export const dockerCommands = { dockerBuildCommand: 'foofoo', dockerPushCommand: 'barbar', diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js index 310398b01cf..26f0e506829 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js @@ -18,7 +18,6 @@ import { UNFINISHED_STATUS, DELETE_SCHEDULED, ALERT_DANGER_IMAGE, - ALERT_DANGER_IMPORTING, MISSING_OR_DELETED_IMAGE_BREADCRUMB, MISSING_OR_DELETED_IMAGE_TITLE, MISSING_OR_DELETED_IMAGE_MESSAGE, @@ -34,7 +33,6 @@ import Tracking from '~/tracking'; import { graphQLImageDetailsMock, graphQLDeleteImageRepositoryTagsMock, - graphQLDeleteImageRepositoryTagImportingErrorMock, graphQLProjectImageRepositoriesDetailsMock, containerRepositoryMock, graphQLEmptyImageDetailsMock, @@ -341,7 +339,6 @@ describe('Details Page', () => { const config = { isAdmin: true, garbageCollectionHelpPagePath: 'baz', - containerRegistryImportingHelpPagePath: 'https://foobar', }; const deleteAlertType = 'success_tag'; @@ -366,38 +363,6 @@ describe('Details Page', () => { expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType }); }); - - describe('importing repository error', () => { - let mutationResolver; - let tagsResolver; - let detailsResolver; - - beforeEach(async () => { - mutationResolver = jest - .fn() - .mockResolvedValue(graphQLDeleteImageRepositoryTagImportingErrorMock); - tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock())); - detailsResolver = jest.fn().mockResolvedValue(graphQLProjectImageRepositoriesDetailsMock); - - mountComponent({ mutationResolver, tagsResolver, detailsResolver }); - await waitForApolloRequestRender(); - }); - - it('displays the proper alert', async () => { - findTagsList().vm.$emit('delete', [cleanTags[0]]); - await nextTick(); - - findDeleteModal().vm.$emit('confirmDelete'); - await waitForPromises(); - - expect(tagsResolver).toHaveBeenCalled(); - expect(detailsResolver).toHaveBeenCalled(); - - const deleteAlert = findDeleteAlert(); - expect(deleteAlert.exists()).toBe(true); - expect(deleteAlert.props('deleteAlertType')).toBe(ALERT_DANGER_IMPORTING); - }); - }); }); describe('Partial Cleanup Alert', () => { diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb index 80a1224abbb..5b74eda34cd 100644 --- a/spec/helpers/tab_helper_spec.rb +++ b/spec/helpers/tab_helper_spec.rb @@ -7,7 +7,7 @@ RSpec.describe TabHelper do describe 'gl_tabs_nav' do it 'creates a tabs navigation' do - expect(helper.gl_tabs_nav).to match(%r{<ul class="nav gl-tabs-nav"><\/ul>}) + expect(helper.gl_tabs_nav).to match(%r{<ul class="nav gl-tabs-nav"></ul>}) end it 'captures block output' do diff --git a/spec/lib/banzai/filter/references/reference_filter_spec.rb b/spec/lib/banzai/filter/references/reference_filter_spec.rb index b14b9374364..6d7396ef216 100644 --- a/spec/lib/banzai/filter/references/reference_filter_spec.rb +++ b/spec/lib/banzai/filter/references/reference_filter_spec.rb @@ -148,7 +148,7 @@ RSpec.describe Banzai::Filter::References::ReferenceFilter do include_context 'document nodes' let(:node) { Nokogiri::HTML.fragment('text @reference') } - let(:ref_pattern) { %r{(?<!\w)@(?<user>[a-zA-Z0-9_\-\.]*)}x } + let(:ref_pattern) { %r{(?<!\w)@(?<user>[a-zA-Z0-9_\-.]*)}x } context 'when node has no reference pattern' do let(:node) { Nokogiri::HTML.fragment('random text') } diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb index cbd931c514f..b4be26ef8d2 100644 --- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb +++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do result = filter(%{<pre lang="#{lang}"><code><script>alert(1)</script></code></pre>}) # `(1)` symbols are wrapped by lexer tags. - expect(result.to_html).not_to match(%r{<script>alert.*<\/script>}) + expect(result.to_html).not_to match(%r{<script>alert.*</script>}) # `<>` stands for lexer tags like <span ...>, not <s above. expect(result.to_html).to match(%r{alert(<.*>)?\((<.*>)?1(<.*>)?\)}) diff --git a/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb b/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb index 4bccae04fda..8d15dbc8f2f 100644 --- a/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb @@ -78,7 +78,7 @@ RSpec.describe Banzai::Pipeline::IncidentManagement::TimelineEventPipeline do it 'replaces existing label to a link' do # rubocop:disable Layout/LineLength is_expected.to match( - %r(<p>.+<a href=\"[\w/]+-/issues\?label_name=#{label.name}\".+style=\"background-color: #\d{6}\".*>#{label.name}</span></a></span> ~unknown</p>) + %r(<p>.+<a href="[\w/]+-/issues\?label_name=#{label.name}".+style="background-color: #\d{6}".*>#{label.name}</span></a></span> ~unknown</p>) ) # rubocop:enable Layout/LineLength end diff --git a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb b/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb index 6ef474ad7f9..5f93424faf6 100644 --- a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb @@ -45,7 +45,7 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillWorkItemTypeIdForIssues, :mi it 'sets work_item_type_id only for the given type' do expect(all_issues).to all(have_attributes(work_item_type_id: nil)) - expect { migrate }.to make_queries_matching(/UPDATE \"issues\" SET "work_item_type_id"/, 2) + expect { migrate }.to make_queries_matching(/UPDATE "issues" SET "work_item_type_id"/, 2) all_issues.each(&:reload) expect([issue1, issue2, issue3]).to all(have_attributes(work_item_type_id: issue_type.id)) diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index c4a6641ff6b..911b0fa7192 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -305,7 +305,7 @@ RSpec.describe Gitlab::Ci::Config do it 'raises error' do expect { config }.to raise_error( described_class::ConfigError, - /\!reference \["job-2", "before_script"\] is part of a circular chain/ + /!reference \["job-2", "before_script"\] is part of a circular chain/ ) end end diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb index e730afc72b5..c94ed1f8d6d 100644 --- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb @@ -95,7 +95,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do context 'when all files under schema path are explicitly listed' do # We only care about the part that comes before report-format.json # https://rubular.com/r/N8Juz7r8hYDYgD - filename_regex = /(?<report_type>[-\w]*)\-report-format.json/ + filename_regex = /(?<report_type>[-\w]*)-report-format.json/ versions = Dir.glob(File.join(schema_path, "*", File::SEPARATOR)).map { |path| path.split("/").last } diff --git a/spec/lib/gitlab/gon_helper_spec.rb b/spec/lib/gitlab/gon_helper_spec.rb index 594b468551b..6e8997d51c3 100644 --- a/spec/lib/gitlab/gon_helper_spec.rb +++ b/spec/lib/gitlab/gon_helper_spec.rb @@ -40,11 +40,11 @@ RSpec.describe Gitlab::GonHelper do end end - describe 'sentry configuration' do + context 'when sentry is configured' do let(:clientside_dsn) { 'https://xxx@sentry.example.com/1' } let(:environment) { 'staging' } - describe 'legacy sentry integration' do + context 'with legacy sentry configuration' do before do stub_config(sentry: { enabled: true, clientside_dsn: clientside_dsn, environment: environment }) end @@ -57,7 +57,7 @@ RSpec.describe Gitlab::GonHelper do end end - describe 'sentry integration' do + context 'with sentry settings' do before do stub_application_setting(sentry_enabled: true) stub_application_setting(sentry_clientside_dsn: clientside_dsn) diff --git a/spec/lib/gitlab/import_export/saver_spec.rb b/spec/lib/gitlab/import_export/saver_spec.rb index f5eed81f73c..a34e68ecd19 100644 --- a/spec/lib/gitlab/import_export/saver_spec.rb +++ b/spec/lib/gitlab/import_export/saver_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Gitlab::ImportExport::Saver do subject.save # rubocop:disable Rails/SaveBang expect(ImportExportUpload.find_by(project: project).export_file.url) - .to match(%r[\/uploads\/-\/system\/import_export_upload\/export_file.*]) + .to match(%r[/uploads/-/system/import_export_upload/export_file.*]) end it 'logs metrics after saving' do diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb index bc116e6a20d..2ead188dc93 100644 --- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb +++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb @@ -157,7 +157,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the core API endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/api\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/api\Z}) end it 'has the api_version' do @@ -171,7 +171,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the RBAC API group endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/apis\/rbac.authorization.k8s.io\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/apis/rbac.authorization.k8s.io\Z}) end it 'has the api_version' do @@ -185,7 +185,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the Istio API group endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/apis\/networking.istio.io\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/apis/networking.istio.io\Z}) end it 'has the api_version' do @@ -199,7 +199,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the extensions API group endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/apis\/serving.knative.dev\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/apis/serving.knative.dev\Z}) end it 'has the api_version' do @@ -213,7 +213,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the networking API group endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/apis\/networking.k8s.io\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/apis/networking.k8s.io\Z}) end it 'has the api_version' do @@ -227,7 +227,7 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do it_behaves_like 'a Kubeclient' it 'has the metrics API group endpoint' do - expect(subject.api_endpoint.to_s).to match(%r{\/apis\/metrics.k8s.io\Z}) + expect(subject.api_endpoint.to_s).to match(%r{/apis/metrics.k8s.io\Z}) end it 'has the api_version' do diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb index 60bb006673f..a34ddf8773c 100644 --- a/spec/lib/gitlab/sql/pattern_spec.rb +++ b/spec/lib/gitlab/sql/pattern_spec.rb @@ -210,7 +210,7 @@ RSpec.describe Gitlab::SQL::Pattern do let(:query) { 'foo' } it 'returns a single ILIKE condition' do - expect(fuzzy_arel_match.to_sql).to match(/title.*I?LIKE '\%foo\%'/) + expect(fuzzy_arel_match.to_sql).to match(/title.*I?LIKE '%foo%'/) end end @@ -232,7 +232,7 @@ RSpec.describe Gitlab::SQL::Pattern do let(:query) { 'foo baz' } it 'returns a joining LIKE condition using a AND' do - expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%'/) + expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '%foo%' AND .*title.*I?LIKE '%baz%'/) end end @@ -248,7 +248,7 @@ RSpec.describe Gitlab::SQL::Pattern do let(:query) { 'foo ba' } it 'returns a single ILIKE condition using the longer word' do - expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '\%foo\%'/) + expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '%foo%'/) end end @@ -256,7 +256,7 @@ RSpec.describe Gitlab::SQL::Pattern do let(:query) { 'foo "really bar" baz' } it 'returns a joining LIKE condition using a AND' do - expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%' AND .*title.*I?LIKE '\%really bar\%'/) + expect(fuzzy_arel_match.to_sql).to match(/title.+I?LIKE '%foo%' AND .*title.*I?LIKE '%baz%' AND .*title.*I?LIKE '%really bar%'/) end end @@ -266,7 +266,7 @@ RSpec.describe Gitlab::SQL::Pattern do subject(:fuzzy_arel_match) { Project.fuzzy_arel_match(Route.arel_table[:path], query) } it 'returns a condition with the table and column name' do - expect(fuzzy_arel_match.to_sql).to match(/"routes"."path".*ILIKE '\%foo\%'/) + expect(fuzzy_arel_match.to_sql).to match(/"routes"."path".*ILIKE '%foo%'/) end end end diff --git a/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb b/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb index 24107727a8e..9dba64ff59f 100644 --- a/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb +++ b/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb @@ -44,7 +44,7 @@ RSpec.describe Gitlab::Usage::Metrics::NameSuggestion do let(:operation) { :count } let(:relation) { Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot) } let(:column) { nil } - let(:name_suggestion) { /count_<adjective describing\: '\(issues\.author_id != \d+\)'>_issues_<with>_alert_management_alerts/ } + let(:name_suggestion) { /count_<adjective describing: '\(issues\.author_id != \d+\)'>_issues_<with>_alert_management_alerts/ } end end end @@ -55,7 +55,7 @@ RSpec.describe Gitlab::Usage::Metrics::NameSuggestion do let(:operation) { :distinct_count } let(:relation) { ::Clusters::Cluster.aws_installed.enabled.where(created_at: 30.days.ago..2.days.ago ) } let(:column) { :user_id } - let(:constraints) { /<adjective describing\: '\(clusters.provider_type = \d+ AND \(cluster_providers_aws\.status IN \(\d+\)\) AND clusters\.enabled = TRUE\)'>/ } + let(:constraints) { /<adjective describing: '\(clusters.provider_type = \d+ AND \(cluster_providers_aws\.status IN \(\d+\)\) AND clusters\.enabled = TRUE\)'>/ } let(:name_suggestion) { /count_distinct_user_id_from_#{constraints}_clusters_<with>_#{constraints}_cluster_providers_aws/ } end end @@ -66,7 +66,7 @@ RSpec.describe Gitlab::Usage::Metrics::NameSuggestion do let(:operation) { :sum } let(:relation) { JiraImportState.finished } let(:column) { :imported_issues_count } - let(:name_suggestion) { /sum_imported_issues_count_from_<adjective describing\: '\(jira_imports\.status = \d+\)'>_jira_imports/ } + let(:name_suggestion) { /sum_imported_issues_count_from_<adjective describing: '\(jira_imports\.status = \d+\)'>_jira_imports/ } end end diff --git a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb index 7e8b15d23db..83a4ea8e948 100644 --- a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb +++ b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb @@ -45,7 +45,7 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do it_behaves_like 'name suggestion' do # corresponding metric is collected with count(Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot), start: issue_minimum_id, finish: issue_maximum_id) let(:key_path) { 'counts.issues_created_manually_from_alerts' } - let(:name_suggestion) { /count_<adjective describing\: '\(issues\.author_id != \d+\)'>_issues_<with>_alert_management_alerts/ } + let(:name_suggestion) { /count_<adjective describing: '\(issues\.author_id != \d+\)'>_issues_<with>_alert_management_alerts/ } end end end @@ -54,7 +54,7 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do it_behaves_like 'name suggestion' do # corresponding metric is collected with distinct_count(::Clusters::Cluster.aws_installed.enabled.where(time_period), :user_id) let(:key_path) { 'usage_activity_by_stage_monthly.configure.clusters_platforms_eks' } - let(:constraints) { /<adjective describing\: '\(clusters.provider_type = \d+ AND \(cluster_providers_aws\.status IN \(\d+\)\) AND clusters\.enabled = TRUE\)'>/ } + let(:constraints) { /<adjective describing: '\(clusters.provider_type = \d+ AND \(cluster_providers_aws\.status IN \(\d+\)\) AND clusters\.enabled = TRUE\)'>/ } let(:name_suggestion) { /count_distinct_user_id_from_#{constraints}_clusters_<with>_#{constraints}_cluster_providers_aws/ } end end @@ -63,7 +63,7 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do it_behaves_like 'name suggestion' do # corresponding metric is collected with sum(JiraImportState.finished, :imported_issues_count) let(:key_path) { 'counts.jira_imports_total_imported_issues_count' } - let(:name_suggestion) { /sum_imported_issues_count_from_<adjective describing\: '\(jira_imports\.status = \d+\)'>_jira_imports/ } + let(:name_suggestion) { /sum_imported_issues_count_from_<adjective describing: '\(jira_imports\.status = \d+\)'>_jira_imports/ } end end @@ -71,7 +71,7 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do it_behaves_like 'name suggestion' do # corresponding metric is collected with add(data[:personal_snippets], data[:project_snippets]) let(:key_path) { 'counts.snippets' } - let(:name_suggestion) { /add_count_<adjective describing\: '\(snippets\.type = 'PersonalSnippet'\)'>_snippets_and_count_<adjective describing\: '\(snippets\.type = 'ProjectSnippet'\)'>_snippets/ } + let(:name_suggestion) { /add_count_<adjective describing: '\(snippets\.type = 'PersonalSnippet'\)'>_snippets_and_count_<adjective describing: '\(snippets\.type = 'ProjectSnippet'\)'>_snippets/ } end end diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index 7b5cfb57707..e84a67c3fba 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -358,7 +358,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s context 'with valid contex' do it 'increments context event counter' do expect(Gitlab::Redis::HLL).to receive(:add) do |kwargs| - expect(kwargs[:key]).to match(/^#{default_context}\_.*/) + expect(kwargs[:key]).to match(/^#{default_context}_.*/) end described_class.track_event_in_context(context_event, values: entity1, context: default_context) diff --git a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb index 9d712cfc9f1..e7aa2b7edca 100644 --- a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Sidebars::Projects::Menus::RepositoryMenu do +RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :source_code_management do let_it_be(:project) { create(:project, :repository) } let(:user) { project.first_owner } @@ -36,51 +36,68 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu do end context 'for menu items' do - let(:ref) { 'master' } + shared_examples_for 'repository menu item link for' do |item_id| + let(:ref) { 'master' } + let(:item_id) { item_id } + subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id }.link } - subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id } } + using RSpec::Parameterized::TableSyntax - describe 'Commits' do - let_it_be(:item_id) { :commits } + let(:context) do + Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: ref, + ref_type: ref_type) + end - context 'when there is a ref_type' do - let(:context) do - Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: ref, - ref_type: ref_type) - end + where(:feature_flag_enabled, :ref_type, :link) do + true | nil | lazy { "#{route}?ref_type=heads" } + true | 'heads' | lazy { "#{route}?ref_type=heads" } + true | 'tags' | lazy { "#{route}?ref_type=tags" } + false | nil | lazy { route } + false | 'heads' | lazy { route } + false | 'tags' | lazy { route } + end - let(:ref_type) { 'tags' } + with_them do + before do + stub_feature_flags(use_ref_type_parameter: feature_flag_enabled) + end - it 'has a links to commits with ref_type' do - expect(subject.link).to eq("/#{project.full_path}/-/commits/#{ref}?ref_type=#{ref_type}") + it 'has a link with the fully qualifed ref route' do + expect(subject).to eq(link) end end - context 'when there is no ref_type' do - let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: ref) } + context 'when ref is not the default' do + let(:ref) { 'nonmain' } - context 'and the use_ref_type_parameter is disabled' do - before do - stub_feature_flags(use_ref_type_parameter: false) - end + context 'and ref_type is not provided' do + let(:ref_type) { nil } - it 'has a links to commits' do - expect(subject.link).to eq("/#{project.full_path}/-/commits/#{ref}") - end + it { is_expected.to eq(route) } end - context 'and the use_ref_type_parameter flag is enabled' do - it 'has a links to commits ref_type' do - expect(subject.link).to eq("/#{project.full_path}/-/commits/#{ref}?ref_type=heads") - end + context 'and ref_type is provided' do + let(:ref_type) { 'heads' } + + it { is_expected.to eq("#{route}?ref_type=heads") } end end end + describe 'Commits' do + let_it_be(:item_id) { :commits } + + it_behaves_like 'repository menu item link for', :commits do + let(:route) { "/#{project.full_path}/-/commits/#{ref}" } + end + end + describe 'Contributors' do let_it_be(:item_id) { :contributors } context 'when analytics is disabled' do + subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id } } + before do project.project_feature.update!(analytics_access_level: ProjectFeature::DISABLED) end @@ -93,53 +110,15 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu do project.project_feature.update!(analytics_access_level: ProjectFeature::ENABLED) end - using RSpec::Parameterized::TableSyntax - it { is_expected.not_to be_nil } - - shared_examples_for 'contributors menu link' do - with_them do - before do - stub_feature_flags(use_ref_type_parameter: feature_flag_enabled) - end - - it 'has a link to graphs with the fully qualifed ref route' do - expect(subject.link).to eq(link) - end - end + it_behaves_like 'repository menu item link for', :contributors do + let(:route) { "/#{project.full_path}/-/graphs/#{ref}" } end + end + end - describe 'link' do - let(:context) do - Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: ref, - ref_type: ref_type) - end - - it_behaves_like 'contributors menu link' do - where(:feature_flag_enabled, :ref_type, :link) do - true | nil | lazy { "/#{project.full_path}/-/graphs/#{ref}?ref_type=heads" } - true | 'heads' | lazy { "/#{project.full_path}/-/graphs/#{ref}?ref_type=heads" } - true | 'tags' | lazy { "/#{project.full_path}/-/graphs/#{ref}?ref_type=tags" } - false | nil | lazy { "/#{project.full_path}/-/graphs/#{ref}" } - false | 'heads' | lazy { "/#{project.full_path}/-/graphs/#{ref}" } - false | 'tags' | lazy { "/#{project.full_path}/-/graphs/#{ref}" } - end - end - - context 'when ref is not the default' do - let(:ref) { 'nonmain' } - - it_behaves_like 'contributors menu link' do - where(:feature_flag_enabled, :ref_type, :link) do - true | nil | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}" } - true | 'heads' | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}?ref_type=heads" } - true | 'tags' | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}?ref_type=tags" } - false | nil | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}" } - false | 'heads' | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}" } - false | 'tags' | lazy { "/#{project.full_path}/-/graphs/#{context.current_ref}" } - end - end - end - end + describe 'Network' do + it_behaves_like 'repository menu item link for', :graphs do + let(:route) { "/#{project.full_path}/-/network/#{ref}" } end end end diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb index 1812ac0288d..cdc298d685e 100644 --- a/spec/mailers/emails/profile_spec.rb +++ b/spec/mailers/emails/profile_spec.rb @@ -152,7 +152,7 @@ RSpec.describe Emails::Profile do end it 'includes the email reason' do - is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} + is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} end end end @@ -188,7 +188,7 @@ RSpec.describe Emails::Profile do end it 'includes the email reason' do - is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} + is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} end context 'with User does not exist' do @@ -223,7 +223,7 @@ RSpec.describe Emails::Profile do end it 'includes the email reason' do - is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} + is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} end end @@ -274,7 +274,7 @@ RSpec.describe Emails::Profile do end it 'includes the email reason' do - is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} + is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} end end @@ -302,7 +302,7 @@ RSpec.describe Emails::Profile do end it 'includes the email reason' do - is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} + is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} end end end @@ -328,7 +328,7 @@ RSpec.describe Emails::Profile do end shared_examples 'includes the email reason' do - it { is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost<\/a>} } + it { is_expected.to have_body_text %r{You're receiving this email because of your account on <a .*>localhost</a>} } end shared_examples 'valid use case' do diff --git a/spec/models/ci/group_variable_spec.rb b/spec/models/ci/group_variable_spec.rb index fc5a9c879f6..1d904ac8025 100644 --- a/spec/models/ci/group_variable_spec.rb +++ b/spec/models/ci/group_variable_spec.rb @@ -2,10 +2,11 @@ require 'spec_helper' -RSpec.describe Ci::GroupVariable do +RSpec.describe Ci::GroupVariable, feature_category: :pipeline_authoring do subject { build(:ci_group_variable) } it_behaves_like "CI variable" + it_behaves_like 'includes Limitable concern' it { is_expected.to include_module(Presentable) } it { is_expected.to include_module(Ci::Maskable) } diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index 5f2b5971508..3884bbae373 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -2,10 +2,11 @@ require 'spec_helper' -RSpec.describe Ci::Variable do +RSpec.describe Ci::Variable, feature_category: :pipeline_authoring do subject { build(:ci_variable) } it_behaves_like "CI variable" + it_behaves_like 'includes Limitable concern' describe 'validations' do it { is_expected.to include_module(Presentable) } diff --git a/spec/models/release_highlight_spec.rb b/spec/models/release_highlight_spec.rb index 3555dfba769..bd962a8e72f 100644 --- a/spec/models/release_highlight_spec.rb +++ b/spec/models/release_highlight_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do - let(:fixture_dir_glob) { Dir.glob(File.join(Rails.root, 'spec', 'fixtures', 'whats_new', '*.yml')).grep(/\d*\_(\d*\_\d*)\.yml$/) } + let(:fixture_dir_glob) { Dir.glob(File.join(Rails.root, 'spec', 'fixtures', 'whats_new', '*.yml')).grep(/\d*_(\d*_\d*)\.yml$/) } before do allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) diff --git a/spec/requests/api/ci/variables_spec.rb b/spec/requests/api/ci/variables_spec.rb index cafb841995d..b27b9054432 100644 --- a/spec/requests/api/ci/variables_spec.rb +++ b/spec/requests/api/ci/variables_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::Ci::Variables do +RSpec.describe API::Ci::Variables, feature_category: :pipeline_authoring do let(:user) { create(:user) } let(:user2) { create(:user) } let!(:project) { create(:project, creator_id: user.id) } @@ -114,73 +114,92 @@ RSpec.describe API::Ci::Variables do describe 'POST /projects/:id/variables' do context 'authorized user with proper permissions' do - it 'creates variable' do - expect do - post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } - end.to change { project.variables.count }.by(1) - - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq('TEST_VARIABLE_2') - expect(json_response['value']).to eq('PROTECTED_VALUE_2') - expect(json_response['protected']).to be_truthy - expect(json_response['masked']).to be_truthy - expect(json_response['raw']).to be_truthy - expect(json_response['variable_type']).to eq('env_var') - end + context 'when the project is below the plan limit for variables' do + it 'creates variable' do + expect do + post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } + end.to change { project.variables.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq('TEST_VARIABLE_2') + expect(json_response['value']).to eq('PROTECTED_VALUE_2') + expect(json_response['protected']).to be_truthy + expect(json_response['masked']).to be_truthy + expect(json_response['raw']).to be_truthy + expect(json_response['variable_type']).to eq('env_var') + end - it 'masks the new value when logging' do - masked_params = { 'key' => 'VAR_KEY', 'value' => '[FILTERED]', 'protected' => 'true', 'masked' => 'true' } + it 'masks the new value when logging' do + masked_params = { 'key' => 'VAR_KEY', 'value' => '[FILTERED]', 'protected' => 'true', 'masked' => 'true' } - expect(::API::API::LOGGER).to receive(:info).with(include(params: include(masked_params))) + expect(::API::API::LOGGER).to receive(:info).with(include(params: include(masked_params))) - post api("/projects/#{project.id}/variables", user), - params: { key: 'VAR_KEY', value: 'SENSITIVE', protected: true, masked: true } - end + post api("/projects/#{project.id}/variables", user), + params: { key: 'VAR_KEY', value: 'SENSITIVE', protected: true, masked: true } + end - it 'creates variable with optional attributes' do - expect do - post api("/projects/#{project.id}/variables", user), params: { variable_type: 'file', key: 'TEST_VARIABLE_2', value: 'VALUE_2' } - end.to change { project.variables.count }.by(1) - - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq('TEST_VARIABLE_2') - expect(json_response['value']).to eq('VALUE_2') - expect(json_response['protected']).to be_falsey - expect(json_response['masked']).to be_falsey - expect(json_response['raw']).to be_falsey - expect(json_response['variable_type']).to eq('file') - end + it 'creates variable with optional attributes' do + expect do + post api("/projects/#{project.id}/variables", user), params: { variable_type: 'file', key: 'TEST_VARIABLE_2', value: 'VALUE_2' } + end.to change { project.variables.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq('TEST_VARIABLE_2') + expect(json_response['value']).to eq('VALUE_2') + expect(json_response['protected']).to be_falsey + expect(json_response['masked']).to be_falsey + expect(json_response['raw']).to be_falsey + expect(json_response['variable_type']).to eq('file') + end - it 'does not allow to duplicate variable key' do - expect do - post api("/projects/#{project.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } - end.to change { project.variables.count }.by(0) + it 'does not allow to duplicate variable key' do + expect do + post api("/projects/#{project.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } + end.to change { project.variables.count }.by(0) - expect(response).to have_gitlab_http_status(:bad_request) - end + expect(response).to have_gitlab_http_status(:bad_request) + end - it 'creates variable with a specific environment scope' do - expect do - post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2', environment_scope: 'review/*' } - end.to change { project.variables.reload.count }.by(1) + it 'creates variable with a specific environment scope' do + expect do + post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'VALUE_2', environment_scope: 'review/*' } + end.to change { project.variables.reload.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq('TEST_VARIABLE_2') + expect(json_response['value']).to eq('VALUE_2') + expect(json_response['environment_scope']).to eq('review/*') + end + + it 'allows duplicated variable key given different environment scopes' do + variable = create(:ci_variable, project: project) - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq('TEST_VARIABLE_2') - expect(json_response['value']).to eq('VALUE_2') - expect(json_response['environment_scope']).to eq('review/*') + expect do + post api("/projects/#{project.id}/variables", user), params: { key: variable.key, value: 'VALUE_2', environment_scope: 'review/*' } + end.to change { project.variables.reload.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq(variable.key) + expect(json_response['value']).to eq('VALUE_2') + expect(json_response['environment_scope']).to eq('review/*') + end end - it 'allows duplicated variable key given different environment scopes' do - variable = create(:ci_variable, project: project) + context 'when the project is at the plan limit for variables' do + it 'returns a variable limit error' do + create(:plan_limits, :default_plan, project_ci_variables: 1) - expect do - post api("/projects/#{project.id}/variables", user), params: { key: variable.key, value: 'VALUE_2', environment_scope: 'review/*' } - end.to change { project.variables.reload.count }.by(1) + expect(project.variables.count).to be(1) - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq(variable.key) - expect(json_response['value']).to eq('VALUE_2') - expect(json_response['environment_scope']).to eq('review/*') + expect do + post api("/projects/#{project.id}/variables", user), params: { key: 'TOO_MANY_VARS', value: 'too many' } + end.not_to change { project.variables.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']['base']).to contain_exactly( + 'Maximum number of project ci variables (1) exceeded' + ) + end end end diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb index bea2365eaa6..9c75d984896 100644 --- a/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb +++ b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb @@ -64,7 +64,7 @@ RSpec.describe 'Setting Draft status of a merge request' do post_graphql_mutation(mutation, current_user: current_user) expect(response).to have_gitlab_http_status(:success) - expect(mutation_response['mergeRequest']['title']).not_to start_with(/draft\:/) + expect(mutation_response['mergeRequest']['title']).not_to start_with(/draft:/) end it 'unmarks the merge request as `Draft`' do diff --git a/spec/requests/api/graphql_spec.rb b/spec/requests/api/graphql_spec.rb index 1c1ae73ddfe..9fd5f7f1430 100644 --- a/spec/requests/api/graphql_spec.rb +++ b/spec/requests/api/graphql_spec.rb @@ -25,12 +25,12 @@ RSpec.describe 'GraphQL' do "query_analysis.used_fields" => ['Query.echo'], "query_analysis.used_deprecated_fields" => [], # query_fingerprint starts with operation name - query_fingerprint: %r{^anonymous\/}, + query_fingerprint: %r{^anonymous/}, duration_s: kind_of(Numeric), trace_type: 'execute_query', operation_name: nil, # operation_fingerprint starts with operation name - operation_fingerprint: %r{^anonymous\/}, + operation_fingerprint: %r{^anonymous/}, is_mutation: false, variables: variables.to_s, query_string: query diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb index a07a8ae4292..b1213dfd66a 100644 --- a/spec/requests/api/group_variables_spec.rb +++ b/spec/requests/api/group_variables_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::GroupVariables do +RSpec.describe API::GroupVariables, feature_category: :pipeline_authoring do let_it_be(:group) { create(:group) } let_it_be(:user) { create(:user) } let_it_be(:variable) { create(:ci_group_variable, group: group) } @@ -88,51 +88,70 @@ RSpec.describe API::GroupVariables do context 'authorized user with proper permissions' do let(:access_level) { :owner } - it 'creates variable' do - expect do - post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } - end.to change { group.variables.count }.by(1) - - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq('TEST_VARIABLE_2') - expect(json_response['value']).to eq('PROTECTED_VALUE_2') - expect(json_response['protected']).to be_truthy - expect(json_response['masked']).to be_truthy - expect(json_response['variable_type']).to eq('env_var') - expect(json_response['environment_scope']).to eq('*') - expect(json_response['raw']).to be_truthy + context 'when the group is below the plan limit for variables' do + it 'creates variable' do + expect do + post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } + end.to change { group.variables.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq('TEST_VARIABLE_2') + expect(json_response['value']).to eq('PROTECTED_VALUE_2') + expect(json_response['protected']).to be_truthy + expect(json_response['masked']).to be_truthy + expect(json_response['variable_type']).to eq('env_var') + expect(json_response['environment_scope']).to eq('*') + expect(json_response['raw']).to be_truthy + end + + it 'masks the new value when logging' do + masked_params = { 'key' => 'VAR_KEY', 'value' => '[FILTERED]', 'protected' => 'true', 'masked' => 'true' } + + expect(::API::API::LOGGER).to receive(:info).with(include(params: include(masked_params))) + + post api("/groups/#{group.id}/variables", user), + params: { key: 'VAR_KEY', value: 'SENSITIVE', protected: true, masked: true } + end + + it 'creates variable with optional attributes' do + expect do + post api("/groups/#{group.id}/variables", user), params: { variable_type: 'file', key: 'TEST_VARIABLE_2', value: 'VALUE_2' } + end.to change { group.variables.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(json_response['key']).to eq('TEST_VARIABLE_2') + expect(json_response['value']).to eq('VALUE_2') + expect(json_response['protected']).to be_falsey + expect(json_response['masked']).to be_falsey + expect(json_response['raw']).to be_falsey + expect(json_response['variable_type']).to eq('file') + expect(json_response['environment_scope']).to eq('*') + end + + it 'does not allow to duplicate variable key' do + expect do + post api("/groups/#{group.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } + end.to change { group.variables.count }.by(0) + + expect(response).to have_gitlab_http_status(:bad_request) + end end - it 'masks the new value when logging' do - masked_params = { 'key' => 'VAR_KEY', 'value' => '[FILTERED]', 'protected' => 'true', 'masked' => 'true' } - - expect(::API::API::LOGGER).to receive(:info).with(include(params: include(masked_params))) - - post api("/groups/#{group.id}/variables", user), - params: { key: 'VAR_KEY', value: 'SENSITIVE', protected: true, masked: true } - end + context 'when the group is at the plan limit for variables' do + it 'returns a variable limit error' do + create(:plan_limits, :default_plan, group_ci_variables: 1) - it 'creates variable with optional attributes' do - expect do - post api("/groups/#{group.id}/variables", user), params: { variable_type: 'file', key: 'TEST_VARIABLE_2', value: 'VALUE_2' } - end.to change { group.variables.count }.by(1) - - expect(response).to have_gitlab_http_status(:created) - expect(json_response['key']).to eq('TEST_VARIABLE_2') - expect(json_response['value']).to eq('VALUE_2') - expect(json_response['protected']).to be_falsey - expect(json_response['masked']).to be_falsey - expect(json_response['raw']).to be_falsey - expect(json_response['variable_type']).to eq('file') - expect(json_response['environment_scope']).to eq('*') - end + expect(group.variables.count).to be(1) - it 'does not allow to duplicate variable key' do - expect do - post api("/groups/#{group.id}/variables", user), params: { key: variable.key, value: 'VALUE_2' } - end.to change { group.variables.count }.by(0) + expect do + post api("/groups/#{group.id}/variables", user), params: { key: 'TOO_MANY_VARS', value: 'too many' } + end.not_to change { group.variables.count } - expect(response).to have_gitlab_http_status(:bad_request) + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']['base']).to contain_exactly( + 'Maximum number of group ci variables (1) exceeded' + ) + end end end diff --git a/spec/requests/api/project_debian_distributions_spec.rb b/spec/requests/api/project_debian_distributions_spec.rb index 2b993f24046..b7c9ae73df6 100644 --- a/spec/requests/api/project_debian_distributions_spec.rb +++ b/spec/requests/api/project_debian_distributions_spec.rb @@ -23,13 +23,13 @@ RSpec.describe API::ProjectDebianDistributions do describe 'GET projects/:id/debian_distributions' do let(:url) { "/projects/#{container.id}/debian_distributions" } - it_behaves_like 'Debian distributions read endpoint', 'GET', :success, /^\[{.*"codename":"existing-codename\",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/ + it_behaves_like 'Debian distributions read endpoint', 'GET', :success, /^\[{.*"codename":"existing-codename",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/ end describe 'GET projects/:id/debian_distributions/:codename' do let(:url) { "/projects/#{container.id}/debian_distributions/#{distribution.codename}" } - it_behaves_like 'Debian distributions read endpoint', 'GET', :success, /^{.*"codename":"existing-codename\",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/ + it_behaves_like 'Debian distributions read endpoint', 'GET', :success, /^{.*"codename":"existing-codename",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/ end describe 'GET projects/:id/debian_distributions/:codename/key.asc' do @@ -56,7 +56,7 @@ RSpec.describe API::ProjectDebianDistributions do let(:method) { :delete } let(:url) { "/projects/#{container.id}/debian_distributions/#{distribution.codename}" } - it_behaves_like 'Debian distributions maintainer write endpoint', 'DELETE', :success, /^{\"message\":\"202 Accepted\"}$/ + it_behaves_like 'Debian distributions maintainer write endpoint', 'DELETE', :success, /^{"message":"202 Accepted"}$/ context 'when destroy fails' do before do diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index 3c22f918af5..04c7bad91a8 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -300,7 +300,7 @@ RSpec.describe API::Repositories do type, params = workhorse_send_data expect(type).to eq('git-archive') - expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.tar.gz/) + expect(params['ArchivePath']).to match(/#{project.path}-[^.]+\.tar.gz/) expect(response.parsed_body).to be_empty end @@ -312,7 +312,7 @@ RSpec.describe API::Repositories do type, params = workhorse_send_data expect(type).to eq('git-archive') - expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.zip/) + expect(params['ArchivePath']).to match(/#{project.path}-[^.]+\.zip/) end it 'returns the repository archive archive.tar.bz2' do @@ -323,7 +323,7 @@ RSpec.describe API::Repositories do type, params = workhorse_send_data expect(type).to eq('git-archive') - expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.tar.bz2/) + expect(params['ArchivePath']).to match(/#{project.path}-[^.]+\.tar.bz2/) end context 'when sha does not exist' do @@ -342,7 +342,7 @@ RSpec.describe API::Repositories do type, params = workhorse_send_data expect(type).to eq('git-archive') - expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\-#{path}\.tar.gz/) + expect(params['ArchivePath']).to match(/#{project.path}-[^.]+-#{path}\.tar.gz/) end it 'rate limits user when thresholds hit' do diff --git a/spec/requests/api/unleash_spec.rb b/spec/requests/api/unleash_spec.rb index 4d382f91023..c324ddeacd7 100644 --- a/spec/requests/api/unleash_spec.rb +++ b/spec/requests/api/unleash_spec.rb @@ -88,85 +88,6 @@ RSpec.describe API::Unleash do end end - shared_examples_for 'support multiple environments' do - let!(:client) { create(:operations_feature_flags_client, project: project) } - let!(:base_headers) { { "UNLEASH-INSTANCEID" => client.token } } - let!(:headers) { base_headers.merge({ "UNLEASH-APPNAME" => "test" }) } - - let!(:feature_flag_1) do - create(:operations_feature_flag, name: "feature_flag_1", project: project, active: true) - end - - let!(:feature_flag_2) do - create(:operations_feature_flag, name: "feature_flag_2", project: project, active: false) - end - - before do - create_scope(feature_flag_1, 'production', false) - create_scope(feature_flag_2, 'review/*', true) - end - - it 'does not have N+1 problem' do - control_count = ActiveRecord::QueryRecorder.new { get api(features_url), headers: headers }.count - - create(:operations_feature_flag, name: "feature_flag_3", project: project, active: true) - - expect { get api(features_url), headers: headers }.not_to exceed_query_limit(control_count) - end - - context 'when app name is staging' do - let(:headers) { base_headers.merge({ "UNLEASH-APPNAME" => "staging" }) } - - it 'returns correct active values' do - subject - - feature_flag_1 = json_response['features'].find { |f| f['name'] == 'feature_flag_1' } - feature_flag_2 = json_response['features'].find { |f| f['name'] == 'feature_flag_2' } - - expect(feature_flag_1['enabled']).to eq(true) - expect(feature_flag_2['enabled']).to eq(false) - end - end - - context 'when app name is production' do - let(:headers) { base_headers.merge({ "UNLEASH-APPNAME" => "production" }) } - - it 'returns correct active values' do - subject - - feature_flag_1 = json_response['features'].find { |f| f['name'] == 'feature_flag_1' } - feature_flag_2 = json_response['features'].find { |f| f['name'] == 'feature_flag_2' } - - expect(feature_flag_1['enabled']).to eq(false) - expect(feature_flag_2['enabled']).to eq(false) - end - end - - context 'when app name is review/patch-1' do - let(:headers) { base_headers.merge({ "UNLEASH-APPNAME" => "review/patch-1" }) } - - it 'returns correct active values' do - subject - - feature_flag_1 = json_response['features'].find { |f| f['name'] == 'feature_flag_1' } - feature_flag_2 = json_response['features'].find { |f| f['name'] == 'feature_flag_2' } - - expect(feature_flag_1['enabled']).to eq(true) - expect(feature_flag_2['enabled']).to eq(false) - end - end - - context 'when app name is empty' do - let(:headers) { base_headers } - - it 'returns empty list' do - subject - - expect(json_response['features'].count).to eq(0) - end - end - end - %w(/feature_flags/unleash/:project_id/features /feature_flags/unleash/:project_id/client/features).each do |features_endpoint| describe "GET #{features_endpoint}", :use_clean_rails_redis_caching do let(:features_url) { features_endpoint.sub(':project_id', project_id.to_s) } diff --git a/spec/requests/projects/network_controller_spec.rb b/spec/requests/projects/network_controller_spec.rb new file mode 100644 index 00000000000..954f9655558 --- /dev/null +++ b/spec/requests/projects/network_controller_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::NetworkController, feature_category: :source_code_management do + let_it_be(:project) { create(:project, :repository, :private) } + let(:ref) { 'master' } + + describe 'GET #show' do + subject { get project_network_path(project, ref) } + + context 'when user is unauthorized' do + it 'shows 404' do + subject + expect(response).to redirect_to(new_user_session_path) + end + end + + context 'when user is authorized' do + let(:user) { project.creator } + + before do + sign_in(user) + end + + it 'renders content' do + subject + expect(response).to be_successful + end + + context 'when ref_type is provided' do + subject { get project_network_path(project, ref, ref_type: 'heads') } + + it 'assigns url with ref_type' do + subject + expect(assigns(:url)).to eq(project_network_path(project, ref, format: :json, ref_type: 'heads')) + end + + context 'when the use_ref_type_parameter flag is disabled' do + before do + stub_feature_flags(use_ref_type_parameter: false) + end + + it 'assigns url without ref_type' do + subject + expect(assigns(:url)).to eq(project_network_path(project, ref, format: :json)) + end + end + end + + it 'assigns url' do + subject + expect(assigns(:url)).to eq(project_network_path(project, ref, format: :json)) + end + end + end +end diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb index 7d4fce814f5..f158b11a9fa 100644 --- a/spec/services/projects/download_service_spec.rb +++ b/spec/services/projects/download_service_spec.rb @@ -21,8 +21,8 @@ RSpec.describe Projects::DownloadService do context 'for URLs that are on the whitelist' do before do # `ssrf_filter` resolves the hostname. See https://github.com/carrierwaveuploader/carrierwave/commit/91714adda998bc9e8decf5b1f5d260d808761304 - stub_request(:get, %r{http://[\d\.]+/rails_sample.jpg}).to_return(body: File.read(Rails.root + 'spec/fixtures/rails_sample.jpg')) - stub_request(:get, %r{http://[\d\.]+/doc_sample.txt}).to_return(body: File.read(Rails.root + 'spec/fixtures/doc_sample.txt')) + stub_request(:get, %r{http://[\d.]+/rails_sample.jpg}).to_return(body: File.read(Rails.root + 'spec/fixtures/rails_sample.jpg')) + stub_request(:get, %r{http://[\d.]+/doc_sample.txt}).to_return(body: File.read(Rails.root + 'spec/fixtures/doc_sample.txt')) end context 'an image file' do diff --git a/spec/support/matchers/exceed_query_limit.rb b/spec/support/matchers/exceed_query_limit.rb index 4fd43d7b107..a5a017828b3 100644 --- a/spec/support/matchers/exceed_query_limit.rb +++ b/spec/support/matchers/exceed_query_limit.rb @@ -63,7 +63,7 @@ module ExceedQueryLimitHelpers end end - MARGINALIA_ANNOTATION_REGEX = %r{\s*\/\*.*\*\/}.freeze + MARGINALIA_ANNOTATION_REGEX = %r{\s*/\*.*\*/}.freeze DB_QUERY_RE = Regexp.union( [ diff --git a/spec/support/shared_examples/features/container_registry_shared_examples.rb b/spec/support/shared_examples/features/container_registry_shared_examples.rb index 784f82fdda1..06b2b8c621c 100644 --- a/spec/support/shared_examples/features/container_registry_shared_examples.rb +++ b/spec/support/shared_examples/features/container_registry_shared_examples.rb @@ -7,19 +7,3 @@ RSpec.shared_examples 'handling feature network errors with the container regist expect(page).to have_content 'We are having trouble connecting to the Container Registry' end end - -RSpec.shared_examples 'rejecting tags destruction for an importing repository on' do |tags: []| - it 'rejects the tag destruction operation' do - service = instance_double('Projects::ContainerRepository::DeleteTagsService') - expect(service).to receive(:execute).with(container_repository) { { status: :error, message: 'repository importing' } } - expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: tags) { service } - - first('[data-testid="additional-actions"]').click - first('[data-testid="single-delete-button"]').click - expect(find('.modal .modal-title')).to have_content _('Remove tag') - find('.modal .modal-footer .btn-danger').click - - expect(page).to have_content('Tags temporarily cannot be marked for deletion. Please try again in a few minutes.') - expect(page).to have_link('More details', href: help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion')) - end -end diff --git a/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb index 8d1502bed84..7a3b94ad81d 100644 --- a/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb +++ b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb @@ -55,7 +55,7 @@ RSpec.shared_examples 'wiki file attachments' do wait_for_requests expect(page.find('#wiki_content').value) - .to match(%r{\!\[dk\]\(uploads/\h{32}/dk\.png\)$}) + .to match(%r{!\[dk\]\(uploads/\h{32}/dk\.png\)$}) end it 'the links point to the wiki root url' do diff --git a/spec/support/shared_examples/mailers/notify_shared_examples.rb b/spec/support/shared_examples/mailers/notify_shared_examples.rb index 919311adc96..b0cbf0b0d65 100644 --- a/spec/support/shared_examples/mailers/notify_shared_examples.rb +++ b/spec/support/shared_examples/mailers/notify_shared_examples.rb @@ -75,7 +75,7 @@ RSpec.shared_examples 'a new thread email with reply-by-email enabled' do aggregate_failures do is_expected.to have_header('Message-ID', "<#{route_key}@#{host}>") - is_expected.to have_header('References', /\A<reply\-.*@#{host}>\Z/ ) + is_expected.to have_header('References', /\A<reply-.*@#{host}>\Z/ ) end end end @@ -91,7 +91,7 @@ RSpec.shared_examples 'a thread answer email with reply-by-email enabled' do aggregate_failures do is_expected.to have_header('Message-ID', /\A<.*@#{host}>\Z/) is_expected.to have_header('In-Reply-To', "<#{route_key}@#{host}>") - is_expected.to have_header('References', /\A<reply\-.*@#{host}> <#{route_key}@#{host}>\Z/ ) + is_expected.to have_header('References', /\A<reply-.*@#{host}> <#{route_key}@#{host}>\Z/ ) is_expected.to have_subject(/^Re: /) end end diff --git a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb index 65b40b3b2b8..f5835460a77 100644 --- a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb @@ -154,7 +154,7 @@ RSpec.shared_examples 'group and project packages query' do end it 'throws an error' do - expect_graphql_errors_to_include(/Argument \'sort\' on Field \'packages\' has an invalid value/) + expect_graphql_errors_to_include(/Argument 'sort' on Field 'packages' has an invalid value/) end end diff --git a/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb b/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb index a6f5b3862a2..0e79e32b78a 100644 --- a/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb +++ b/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb @@ -275,7 +275,7 @@ RSpec.describe ExceedQueryLimitHelpers do expect(test_matcher.log_message) .to match(%r{ORDER BY.*#{TestQueries.table_name}.*LIMIT 1}) expect(test_matcher.log_message) - .not_to match(%r{\/\*.*correlation_id.*\*\/}) + .not_to match(%r{/\*.*correlation_id.*\*/}) end end end diff --git a/spec/uploaders/personal_file_uploader_spec.rb b/spec/uploaders/personal_file_uploader_spec.rb index d2eae5d7a54..1373ccac23d 100644 --- a/spec/uploaders/personal_file_uploader_spec.rb +++ b/spec/uploaders/personal_file_uploader_spec.rb @@ -43,8 +43,8 @@ RSpec.describe PersonalFileUploader do it 'builds correct paths for both local and remote storage' do paths = uploader.upload_paths('test.jpg') - expect(paths.first).to match(%r[\h+\/test.jpg]) - expect(paths.second).to match(%r[^personal_snippet\/\d+\/\h+\/test.jpg]) + expect(paths.first).to match(%r[\h+/test.jpg]) + expect(paths.second).to match(%r[^personal_snippet/\d+/\h+/test.jpg]) end end @@ -52,7 +52,7 @@ RSpec.describe PersonalFileUploader do it_behaves_like 'builds correct paths', store_dir: %r[uploads/-/system/personal_snippet/\d+/\h+], upload_path: %r[\h+/\S+], - absolute_path: %r[#{CarrierWave.root}/uploads/-/system/personal_snippet\/\d+\/\h+\/\S+$] + absolute_path: %r[#{CarrierWave.root}/uploads/-/system/personal_snippet/\d+/\h+/\S+$] it_behaves_like '#base_dir' it_behaves_like '#to_h' @@ -67,7 +67,7 @@ RSpec.describe PersonalFileUploader do it_behaves_like 'builds correct paths', store_dir: %r[\d+/\h+], - upload_path: %r[^personal_snippet\/\d+\/\h+\/<filename>] + upload_path: %r[^personal_snippet/\d+/\h+/<filename>] it_behaves_like '#base_dir' it_behaves_like '#to_h' diff --git a/spec/views/help/index.html.haml_spec.rb b/spec/views/help/index.html.haml_spec.rb index 1d26afcc567..c041c41a412 100644 --- a/spec/views/help/index.html.haml_spec.rb +++ b/spec/views/help/index.html.haml_spec.rb @@ -23,7 +23,7 @@ RSpec.describe 'help/index' do context 'when logged in' do def version_link_regexp(path) base_url = "#{view.source_host_url}/#{view.source_code_group}" - %r{#{Regexp.escape(base_url)}/(gitlab|gitlab\-foss)/#{Regexp.escape(path)}} + %r{#{Regexp.escape(base_url)}/(gitlab|gitlab-foss)/#{Regexp.escape(path)}} end before do diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb index a69d9049035..335214d3c9d 100644 --- a/tooling/danger/project_helper.rb +++ b/tooling/danger/project_helper.rb @@ -105,7 +105,7 @@ module Tooling %r{\Arubocop/cop/migration(/|\.rb)} => :database, %r{\A(\.ruby-version\z|\.nvmrc\z|\.tool-versions\z)} => :tooling, - %r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :tooling, + %r{\A(\.gitlab-ci\.yml\z|\.gitlab/ci)} => :tooling, %r{\A\.codeclimate\.yml\z} => :tooling, %r{\Alefthook.yml\z} => :tooling, %r{\A\.editorconfig\z} => :tooling, |