diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-27 21:09:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-27 21:09:04 +0300 |
commit | 7424d727b85dc0ac19544020a092f462a894a7df (patch) | |
tree | 88e0cc41297973c1082f0aff14925a6fbd27823f | |
parent | 0847321aeec58e8885c18b64abd6732581ec33a4 (diff) |
Add latest changes from gitlab-org/gitlab@master
91 files changed, 593 insertions, 801 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6f60343a96f..a5f07b312fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -119,6 +119,9 @@ workflow: variables: <<: *default-ruby-variables PIPELINE_NAME: 'Ruby $RUBY_VERSION $CI_COMMIT_BRANCH branch pipeline' + - if: '$CI_PROJECT_PATH == "gitlab/gitaly" && $CI_PIPELINE_SOURCE == "parent_pipeline" && $GITALY_TEST' + variables: + PIPELINE_NAME: 'Gitaly Rails Test Pipeline' variables: PG_VERSION: "14" diff --git a/.rubocop.yml b/.rubocop.yml index 8edba38cc65..dcd66eeea92 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -40,6 +40,7 @@ AllCops: TargetRubyVersion: <%= RUBY_VERSION[/^\d+\.\d+/, 0] %> TargetRailsVersion: 6.0 Exclude: + - 'gems/**/*' - 'vendor/**/*' - 'node_modules/**/*' - 'db/fixtures/**/*' diff --git a/app/assets/javascripts/admin/users/components/actions/ban.vue b/app/assets/javascripts/admin/users/components/actions/ban.vue index d7bdceb4798..36dcde619cf 100644 --- a/app/assets/javascripts/admin/users/components/actions/ban.vue +++ b/app/assets/javascripts/admin/users/components/actions/ban.vue @@ -12,7 +12,7 @@ const messageHtml = ` <li>${s__("AdminUsers|The user can't log in.")}</li> <li>${s__("AdminUsers|The user can't access git repositories.")}</li> <li>${s__( - 'AdminUsers|Issues and merge requests authored by this user are hidden from other users.', + 'AdminUsers|Projects, issues, merge requests, and comments of this user are hidden from other users.', )}</li> </ul> <p>${s__('AdminUsers|You can unban their account in the future. Their data remains intact.')}</p> diff --git a/app/assets/javascripts/analytics/shared/constants.js b/app/assets/javascripts/analytics/shared/constants.js index 25699c17b10..7ec7eac24ec 100644 --- a/app/assets/javascripts/analytics/shared/constants.js +++ b/app/assets/javascripts/analytics/shared/constants.js @@ -39,8 +39,8 @@ export const DORA_METRICS = { }; const VSA_FLOW_METRICS_GROUP = { - key: 'key_metrics', - title: s__('ValueStreamAnalytics|Key metrics'), + key: 'lifecycle_metrics', + title: s__('ValueStreamAnalytics|Lifecycle metrics'), keys: Object.values(FLOW_METRICS), }; diff --git a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue index 4074e50a706..947a952de3c 100644 --- a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue +++ b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue @@ -1,9 +1,8 @@ <script> -import { GlDropdownItem, GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui'; +import { GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui'; export default { components: { - GlDropdownItem, GlAvatarLabeled, GlLoadingIcon, }, @@ -43,7 +42,7 @@ export default { data() { return { - selectedIndex: 0, + selectedIndex: -1, }; }, @@ -95,7 +94,7 @@ export default { watch: { items() { - this.selectedIndex = 0; + this.selectedIndex = -1; }, selectedIndex() { this.scrollIntoView(); @@ -193,7 +192,7 @@ export default { }, scrollIntoView() { - this.$refs.dropdownItems[this.selectedIndex].$el.scrollIntoView({ block: 'nearest' }); + this.$refs.dropdownItems[this.selectedIndex]?.scrollIntoView({ block: 'nearest' }); }, selectItem(index) { @@ -215,73 +214,85 @@ export default { </script> <template> - <div> - <ul - v-if="!loading" - :class="{ show: items.length > 0 }" - class="gl-dropdown dropdown-menu gl-relative gl-m-0!" - data-testid="content-editor-suggestions-dropdown" - > - <div class="gl-dropdown-inner gl-overflow-y-auto"> - <gl-dropdown-item - v-for="(item, index) in items" - ref="dropdownItems" - :key="index" - :class="{ 'gl-bg-gray-50': index === selectedIndex }" - @click="selectItem(index)" + <div class="gl-new-dropdown content-editor-suggestions-dropdown"> + <div class="gl-new-dropdown-panel gl-display-block! gl-absolute"> + <div class="gl-new-dropdown-inner"> + <ul + v-if="!loading && items.length > 0" + class="gl-new-dropdown-contents" + data-testid="content-editor-suggestions-dropdown" > - <gl-avatar-labeled - v-if="isUser" - :label="item.username" - :sub-label="avatarSubLabel(item)" - :src="item.avatar_url" - :entity-name="item.username" - :shape="item.type === 'Group' ? 'rect' : 'circle'" - :size="32" - /> - <span v-if="isIssue || isMergeRequest"> - <small>{{ item.iid }}</small> - {{ item.title }} - </span> - <span v-if="isVulnerability || isSnippet"> - <small>{{ item.id }}</small> - {{ item.title }} - </span> - <span v-if="isEpic"> - <small>{{ item.reference }}</small> - {{ item.title }} - </span> - <span v-if="isMilestone"> - {{ item.title }} - </span> - <span v-if="isLabel" class="gl-display-flex gl-align-items-center"> - <span - data-testid="label-color-box" - class="gl-rounded-base gl-display-block gl-w-5 gl-h-5 gl-mr-3" - :style="{ backgroundColor: item.color }" - ></span> - {{ item.title }} - </span> - <span v-if="isCommand"> - /{{ item.name }} <small> {{ item.params[0] }} </small><br /> - <em> - <small> {{ item.description }} </small> - </em> - </span> - <div v-if="isEmoji" class="gl-display-flex gl-align-items-center"> - <div class="gl-pr-4 gl-font-lg">{{ item.e }}</div> - <div class="gl-flex-grow-1"> - {{ item.name }}<br /> - <small>{{ item.d }}</small> + <li + v-for="(item, index) in items" + :key="index" + role="presentation" + class="gl-new-dropdown-item" + :class="{ focused: index === selectedIndex }" + > + <div + ref="dropdownItems" + type="button" + role="menuitem" + class="gl-new-dropdown-item-content" + @click="selectItem(index)" + > + <div class="gl-new-dropdown-item-text-wrapper"> + <gl-avatar-labeled + v-if="isUser" + :label="item.username" + :sub-label="avatarSubLabel(item)" + :src="item.avatar_url" + :entity-name="item.username" + :shape="item.type === 'Group' ? 'rect' : 'circle'" + :size="32" + /> + <span v-if="isIssue || isMergeRequest"> + <small>{{ item.iid }}</small> + {{ item.title }} + </span> + <span v-if="isVulnerability || isSnippet"> + <small>{{ item.id }}</small> + {{ item.title }} + </span> + <span v-if="isEpic"> + <small>{{ item.reference }}</small> + {{ item.title }} + </span> + <span v-if="isMilestone"> + {{ item.title }} + </span> + <span v-if="isLabel" class="gl-display-flex"> + <span + data-testid="label-color-box" + class="dropdown-label-box gl-flex-shrink-0 gl-top-0 gl-mr-3" + :style="{ backgroundColor: item.color }" + ></span> + {{ item.title }} + </span> + <div v-if="isCommand"> + <div class="gl-mb-1"> + <span class="gl-font-weight-bold">/{{ item.name }}</span> + <em class="gl-text-gray-500 gl-font-sm">{{ item.params[0] }}</em> + </div> + <small class="gl-text-gray-500"> {{ item.description }} </small> + </div> + <div v-if="isEmoji" class="gl-display-flex gl-align-items-center"> + <div class="gl-pr-4 gl-font-lg">{{ item.e }}</div> + <div class="gl-flex-grow-1"> + {{ item.name }}<br /> + <small>{{ item.d }}</small> + </div> + </div> + </div> + </div> + </li> + </ul> + <div v-if="loading" class="gl-new-dropdown show dropdown-menu gl-relative gl-m-0!"> + <div class="gl-new-dropdown-inner gl-overflow-y-auto"> + <div class="gl-px-5"> + <gl-loading-icon size="sm" class="gl-display-inline-block" /> {{ __('Loading...') }} </div> </div> - </gl-dropdown-item> - </div> - </ul> - <div v-if="loading" class="gl-dropdown show dropdown-menu gl-relative gl-m-0!"> - <div class="gl-dropdown-inner gl-overflow-y-auto"> - <div class="gl-px-5"> - <gl-loading-icon size="sm" class="gl-display-inline-block" /> {{ __('Loading...') }} </div> </div> </div> diff --git a/app/assets/javascripts/pages/groups/new/components/app.vue b/app/assets/javascripts/pages/groups/new/components/app.vue index 3ee15077d00..876e85e4a47 100644 --- a/app/assets/javascripts/pages/groups/new/components/app.vue +++ b/app/assets/javascripts/pages/groups/new/components/app.vue @@ -1,6 +1,6 @@ <script> -import importGroupIllustration from '@gitlab/svgs/dist/illustrations/group-import.svg?raw'; -import newGroupIllustration from '@gitlab/svgs/dist/illustrations/group-new.svg?raw'; +import GROUP_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/group-import.svg?url'; +import GROUP_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/group-new.svg?url'; import { s__ } from '~/locale'; import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue'; @@ -69,12 +69,12 @@ export default { description: s__( 'GroupsNew|Assemble related projects together and grant members access to several projects at once.', ), - illustration: newGroupIllustration, details: createGroupDescriptionDetails, detailProps: { parentGroupName: this.parentGroupName, importExistingGroupPath: this.importExistingGroupPath, }, + imageSrc: GROUP_NEW_SVG_URL, }, { name: 'import-group-pane', @@ -83,8 +83,8 @@ export default { description: s__( 'GroupsNew|Import a group and related data from another GitLab instance.', ), - illustration: importGroupIllustration, details: 'Migrate your existing groups from another instance of GitLab.', + imageSrc: GROUP_IMPORT_SVG_URL, }, ]; }, diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue index 6ca83b0b500..a841766a93c 100644 --- a/app/assets/javascripts/projects/new/components/app.vue +++ b/app/assets/javascripts/projects/new/components/app.vue @@ -1,8 +1,8 @@ <script> -import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?raw'; -import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?raw'; -import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?raw'; -import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?raw'; +import PROJECT_CREATE_FROM_TEMPLATE_SVG_URL from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?url'; +import PROJECT_CREATE_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?url'; +import PROJECT_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?url'; +import PROJECT_RUN_CICD_PIPELINES_SVG_URL from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?url'; import SafeHtml from '~/vue_shared/directives/safe_html'; import { s__ } from '~/locale'; import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue'; @@ -19,7 +19,7 @@ const PANELS = [ description: s__( 'ProjectsNew|Create a blank project to store your files, plan your work, and collaborate on code, among other things.', ), - illustration: blankProjectIllustration, + imageSrc: PROJECT_CREATE_NEW_SVG_URL, }, { key: 'template', @@ -29,7 +29,7 @@ const PANELS = [ description: s__( 'ProjectsNew|Create a project pre-populated with the necessary files to get you started quickly.', ), - illustration: createFromTemplateIllustration, + imageSrc: PROJECT_CREATE_FROM_TEMPLATE_SVG_URL, }, { key: 'import', @@ -39,7 +39,7 @@ const PANELS = [ description: s__( 'ProjectsNew|Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.', ), - illustration: importProjectIllustration, + imageSrc: PROJECT_IMPORT_SVG_URL, }, { key: 'ci', @@ -47,7 +47,7 @@ const PANELS = [ selector: '#ci-cd-project-pane', title: s__('ProjectsNew|Run CI/CD for external repository'), description: s__('ProjectsNew|Connect your external repository to GitLab CI/CD.'), - illustration: ciCdProjectIllustration, + imageSrc: PROJECT_RUN_CICD_PIPELINES_SVG_URL, }, ]; diff --git a/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue b/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue index caa85d3eaaf..1b4da047057 100644 --- a/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue +++ b/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue @@ -1,11 +1,7 @@ <script> -import SafeHtml from '~/vue_shared/directives/safe_html'; import Tracking from '~/tracking'; export default { - directives: { - SafeHtml, - }, mixins: [Tracking.mixin()], props: { title: { @@ -38,9 +34,10 @@ export default { @click="track('click_tab', { label: panel.name })" > <div - v-safe-html="panel.illustration" - class="new-namespace-panel-illustration gl-text-white gl-display-flex gl-flex-shrink-0 gl-justify-content-center" - ></div> + class="new-namespace-panel-illustration gl-display-flex gl-flex-shrink-0 gl-justify-content-center" + > + <img aria-hidden :src="panel.imageSrc" /> + </div> <div class="gl-pl-4"> <h3 class="gl-font-size-h2 gl-reset-color"> {{ panel.title }} diff --git a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue index 5ab2e346a7a..4503ba6e561 100644 --- a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue +++ b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue @@ -1,6 +1,5 @@ <script> import { GlBreadcrumb, GlIcon } from '@gitlab/ui'; -import SafeHtml from '~/vue_shared/directives/safe_html'; import NewTopLevelGroupAlert from '~/groups/components/new_top_level_group_alert.vue'; import SuperSidebarToggle from '~/super_sidebar/components/super_sidebar_toggle.vue'; @@ -18,9 +17,6 @@ export default { LegacyContainer, SuperSidebarToggle, }, - directives: { - SafeHtml, - }, props: { title: { type: String, @@ -137,7 +133,9 @@ export default { <template v-if="activePanel"> <div class="gl-display-flex gl-align-items-center gl-py-5"> - <div v-safe-html="activePanel.illustration" class="gl-text-white col-auto"></div> + <div class="col-auto"> + <img aria-hidden :src="activePanel.imageSrc" /> + </div> <div class="col"> <h4>{{ activePanel.title }}</h4> diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss index 2ed955a56b6..4be39d3fe70 100644 --- a/app/assets/stylesheets/components/content_editor.scss +++ b/app/assets/stylesheets/components/content_editor.scss @@ -179,6 +179,17 @@ min-width: auto; } +.content-editor-suggestions-dropdown { + .gl-new-dropdown-panel { + width: max-content; + } + + li.focused div.gl-new-dropdown-item-content { + @include gl-focus($inset: true); + @include gl-bg-gray-50; + } +} + .bubble-menu-form { min-width: 320px; } diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index b663a75f04a..1477f8e0aac 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -45,7 +45,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController projects = project_notifications.map(&:source) ActiveRecord::Associations::Preloader.new( records: projects, - associations: { namespace: [:route, :owner], group: [] } + associations: { namespace: [:route, :owner], group: [], creator: [] } ).call Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 57a9538db15..e6ee4355fd4 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -53,6 +53,10 @@ class ProjectsFinder < UnionFinder init_collection end + if Feature.enabled?(:hide_projects_of_banned_users) + collection = without_created_and_owned_by_banned_user(collection) + end + use_cte = params.delete(:use_cte) collection = Project.wrap_with_cte(collection) if use_cte collection = filter_projects(collection) @@ -282,6 +286,12 @@ class ProjectsFinder < UnionFinder { min_access_level: params[:min_access_level] } end + + def without_created_and_owned_by_banned_user(projects) + return projects if current_user&.can?(:admin_all_resources) + + projects.without_created_and_owned_by_banned_user + end end ProjectsFinder.prepend_mod_with('ProjectsFinder') diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb index 00109212934..8140ee97291 100644 --- a/app/helpers/environment_helper.rb +++ b/app/helpers/environment_helper.rb @@ -79,7 +79,6 @@ module EnvironmentHelper can_destroy_environment: can_destroy_environment?(environment), can_stop_environment: can?(current_user, :stop_environment, environment), can_admin_environment: can?(current_user, :admin_environment, project), - **environment_metrics_path(project, environment), environments_fetch_path: project_environments_path(project, format: :json), environment_edit_path: edit_project_environment_path(project, environment), environment_stop_path: stop_project_environment_path(project, environment), @@ -96,10 +95,4 @@ module EnvironmentHelper def environments_detail_data_json(user, project, environment) environments_detail_data(user, project, environment).to_json end - - def environment_metrics_path(project, environment) - return {} if Feature.enabled?(:remove_monitor_metrics) - - { environment_metrics_path: project_metrics_dashboard_path(project, environment: environment) } - end end diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index 9ae5170d9c8..3360a5256af 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -26,7 +26,7 @@ module EnvironmentsHelper metrics_data = {} metrics_data.merge!(project_metrics_data(project)) if project - metrics_data.merge!(environment_metrics_data(environment, project)) if environment + metrics_data.merge!(environment_metrics_data(environment)) if environment metrics_data.merge!(project_and_environment_metrics_data(project, environment)) if project && environment metrics_data.merge!(static_metrics_data) @@ -66,34 +66,20 @@ module EnvironmentsHelper } end - def environment_metrics_data(environment, project = nil) + def environment_metrics_data(environment) return {} unless environment { - 'metrics_dashboard_base_path' => metrics_dashboard_base_path(environment, project), 'current_environment_name' => environment.name, 'has_metrics' => environment.has_metrics?.to_s, 'environment_state' => environment.state.to_s } end - def metrics_dashboard_base_path(environment, project) - # This is needed to support our transition from environment scoped metric paths to project scoped. - if project - path = project_metrics_dashboard_path(project) - - return path if request.path.include?(path) - end - - project_metrics_dashboard_path(project, environment: environment) - end - def project_and_environment_metrics_data(project, environment) return {} unless project && environment { - 'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json), - 'dashboard_endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json), 'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json), 'operations_settings_path' => project_settings_operations_path(project), 'can_access_operations_settings' => can?(current_user, :admin_operations, project).to_s, diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 9415e7d4dc3..f27f1a17d79 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -547,6 +547,14 @@ module ProjectsHelper project.ssh_url_to_repo end + def can_view_branch_rules? + can?(current_user, :maintainer_access, @project) + end + + def can_push_code? + current_user&.can?(:push_code, @project) + end + private def create_merge_request_path(project, source_project, ref, merge_request) @@ -892,10 +900,6 @@ def can_admin_group_clusters?(project) project.group && project.group.clusters.any? && can?(current_user, :admin_cluster, project.group) end -def can_view_branch_rules? - can?(current_user, :maintainer_access, @project) -end - def branch_rules_path project_settings_repository_path(@project, anchor: 'js-branch-rules') end diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb index 9ec22a659d3..185e1b8e0a8 100644 --- a/app/helpers/web_ide_button_helper.rb +++ b/app/helpers/web_ide_button_helper.rb @@ -33,10 +33,6 @@ module WebIdeButtonHelper can_view_pipeline_editor?(project) && path == project.ci_config_path_or_default end - def can_push_code? - current_user&.can?(:push_code, @project) - end - def fork? !project_fork.nil? && !can_push_code? end diff --git a/app/models/project.rb b/app/models/project.rb index e4d8830ec48..a45b07d94ce 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -904,6 +904,16 @@ class Project < ApplicationRecord scope :for_group_and_its_ancestor_groups, ->(group) { where(namespace_id: group.self_and_ancestors.select(:id)) } scope :is_importing, -> { with_import_state.where(import_state: { status: %w[started scheduled] }) } + scope :without_created_and_owned_by_banned_user, -> do + where_not_exists( + Users::BannedUser.joins( + 'INNER JOIN project_authorizations ON project_authorizations.user_id = banned_users.user_id' + ).where('projects.creator_id = banned_users.user_id') + .where('project_authorizations.project_id = projects.id') + .where(project_authorizations: { access_level: Gitlab::Access::OWNER }) + ) + end + class << self # Searches for a list of projects based on the query given in `query`. # @@ -3169,6 +3179,10 @@ class Project < ApplicationRecord pending_delete? || hidden? end + def created_and_owned_by_banned_user? + creator.banned? && team.max_member_access(creator.id) == Gitlab::Access::OWNER + end + def content_editor_on_issues_feature_flag_enabled? group&.content_editor_on_issues_feature_flag_enabled? || Feature.enabled?(:content_editor_on_issues, self) end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 98acf69a5dc..0891c66853e 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -255,6 +255,10 @@ class ProjectPolicy < BasePolicy condition(:namespace_catalog_available) { namespace_catalog_available? } + condition(:created_and_owned_by_banned_user, scope: :subject) do + Feature.enabled?(:hide_projects_of_banned_users) && @subject.created_and_owned_by_banned_user? + end + # `:read_project` may be prevented in EE, but `:read_project_for_iids` should # not. rule { guest | admin }.enable :read_project_for_iids @@ -901,6 +905,10 @@ class ProjectPolicy < BasePolicy enable :read_model_experiments end + rule { ~admin & created_and_owned_by_banned_user }.policy do + prevent :read_project + end + private def user_is_user? diff --git a/app/presenters/alert_management/alert_presenter.rb b/app/presenters/alert_management/alert_presenter.rb index 659e991e9d8..41831d50692 100644 --- a/app/presenters/alert_management/alert_presenter.rb +++ b/app/presenters/alert_management/alert_presenter.rb @@ -44,22 +44,10 @@ module AlertManagement project.incident_management_setting&.create_issue? end - def show_performance_dashboard_link? - prometheus_alert.present? - end - def incident_issues_link project_incidents_url(project) end - def performance_dashboard_link - if environment - metrics_project_environment_url(project, environment) - else - metrics_project_environments_url(project) - end - end - def email_title [environment&.name, query_title].compact.join(': ') end diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb index 6457127d831..0a3bf4c2a7b 100644 --- a/app/serializers/environment_entity.rb +++ b/app/serializers/environment_entity.rb @@ -27,10 +27,6 @@ class EnvironmentEntity < Grape::Entity ops.merge(except: UNNECESSARY_ENTRIES_FOR_UPCOMING_DEPLOYMENT)) end - expose :metrics_path, if: -> (*) { expose_metrics_path? } do |environment| - metrics_project_environment_path(environment.project, environment) - end - expose :environment_path do |environment| project_environment_path(environment.project, environment) end @@ -101,10 +97,6 @@ class EnvironmentEntity < Grape::Entity def cluster deployment_platform.cluster end - - def expose_metrics_path? - !Feature.enabled?(:remove_monitor_metrics) && environment.has_metrics? - end end EnvironmentEntity.prepend_mod_with('EnvironmentEntity') diff --git a/app/serializers/environment_status_entity.rb b/app/serializers/environment_status_entity.rb index 9318e0c1de8..8865c030d94 100644 --- a/app/serializers/environment_status_entity.rb +++ b/app/serializers/environment_status_entity.rb @@ -15,10 +15,6 @@ class EnvironmentStatusEntity < Grape::Entity metrics_project_environment_deployment_path(es.project, es.environment, es.deployment) end - expose :metrics_monitoring_url, if: ->(*) { can_read_environment? } do |es| - project_metrics_dashboard_path(es.project, environment: es.environment) - end - expose :stop_url, if: ->(*) { can_stop_environment? } do |es| stop_project_environment_path(es.project, es.environment) end diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml index a309e874317..bdcc7dda644 100644 --- a/app/views/admin/hooks/_form.html.haml +++ b/app/views/admin/hooks/_form.html.haml @@ -6,7 +6,7 @@ %p.form-text.text-muted= _('URL must be percent-encoded if necessary.') .form-group = form.label :token, _('Secret token'), class: 'label-bold' - = form.text_field :token, class: 'form-control gl-form-input' + = form.text_field :token, class: 'form-control gl-form-input gl-max-w-48' %p.form-text.text-muted= _('Use this token to validate received payloads.') .form-group = form.label :url, _('Trigger'), class: 'label-bold' diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index d4aeb8dc7e8..5bac2586fe6 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -1,10 +1,9 @@ - page_title @hook.pluralized_name -.row.gl-mt-3 - .col-lg-4 - = render 'shared/web_hooks/title_and_docs', hook: @hook +.gl-mt-5 + = render 'shared/web_hooks/title_and_docs', hook: @hook - .col-lg-8.gl-mb-3 + .gl-mb-3 = gitlab_ui_form_for @hook, as: :hook, url: admin_hooks_path do |f| = render partial: 'form', locals: { form: f, hook: @hook } = f.submit _('Add system hook'), pajamas_button: true diff --git a/app/views/notify/prometheus_alert_fired_email.html.haml b/app/views/notify/prometheus_alert_fired_email.html.haml index cdc97d583df..25dc8e59073 100644 --- a/app/views/notify/prometheus_alert_fired_email.html.haml +++ b/app/views/notify/prometheus_alert_fired_email.html.haml @@ -25,7 +25,3 @@ - if @alert.show_incident_issues_link? %p = link_to(_('View incident issues.'), @alert.incident_issues_link) - -- if @alert.show_performance_dashboard_link? - %p - = link_to(_('View performance dashboard.'), @alert.performance_dashboard_link) diff --git a/app/views/notify/prometheus_alert_fired_email.text.erb b/app/views/notify/prometheus_alert_fired_email.text.erb index b23cd8b6ccc..a9c1d98a396 100644 --- a/app/views/notify/prometheus_alert_fired_email.text.erb +++ b/app/views/notify/prometheus_alert_fired_email.text.erb @@ -18,7 +18,3 @@ <% if @alert.show_incident_issues_link? %> <%= _('View incident issues.') %> <%= @alert.incident_issues_link %> <% end %> - -<% if @alert.show_performance_dashboard_link? %> -<%= _('View the performance dashboard at') %> <%= @alert.performance_dashboard_link %> -<% end %> diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml index 97f5cdb54e5..3ef2c722e98 100644 --- a/app/views/projects/_export.html.haml +++ b/app/views/projects/_export.html.haml @@ -20,10 +20,12 @@ %li= _('Webhooks') %li= _('Any encrypted tokens') - if project.export_status == :finished - = link_to _('Download export'), download_export_project_path(project), - rel: 'nofollow', download: '', method: :get, class: "btn gl-button btn-default", data: { qa_selector: 'download_export_link' } - = link_to _('Generate new export'), generate_new_export_project_path(project), - method: :post, class: "btn gl-button btn-default" + = render Pajamas::ButtonComponent.new(href: download_export_project_path(project), + method: :get, + button_options: { ref: 'nofollow', download: '', data: { qa_selector: 'download_export_link' } }) do + = _('Download export') + = render Pajamas::ButtonComponent.new(href: generate_new_export_project_path(project), method: :post) do + = _('Generate new export') - else - = link_to _('Export project'), export_project_path(project), - method: :post, class: "btn gl-button btn-default", data: { qa_selector: 'export_project_link' } + = render Pajamas::ButtonComponent.new(href: export_project_path(project), method: :post, button_options: { data: { qa_selector: 'export_project_link' } }) do + = _('Export project') diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index ae328cf0d34..3e98383f13e 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -1,8 +1,6 @@ - add_page_specific_style 'page_bundles/branches' - page_title _('Branches') - add_to_breadcrumbs(_('Repository'), project_tree_path(@project)) -- can_access_branch_rules = can?(current_user, :maintainer_access, @project) -- can_push_code = (can? current_user, :push_code, @project) -# Possible values for variables passed down from the projects/branches_controller.rb -# @@ -24,11 +22,11 @@ sorted_by: @sort } } - - if can_access_branch_rules + - if can_view_branch_rules? = link_to project_settings_repository_path(@project, anchor: 'js-branch-rules'), class: 'gl-button btn btn-default' do = s_('Branches|View branch rules') - - if can_push_code + - if can_push_code? = link_to new_project_branch_path(@project), class: 'gl-button btn btn-confirm' do = s_('Branches|New branch') .js-delete-merged-branches.gl-w-7{ data: { @@ -38,7 +36,7 @@ = render_if_exists 'projects/commits/mirror_status' -- if can_access_branch_rules +- if can_view_branch_rules? = render 'branch_rules_info' .js-branch-list{ data: { diverging_counts_endpoint: diverging_commit_counts_namespace_project_branches_path(@project.namespace, @project, format: :json), default_branch: @project.default_branch } } diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index 4d71161c96e..6bc44a9171b 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -2,11 +2,10 @@ - page_title _('Webhooks') - @force_desktop_expanded_sidebar = true -.row.gl-mt-3.js-search-settings-section - .col-lg-4 - = render 'shared/web_hooks/title_and_docs', hook: @hook +.gl-mt-3.js-search-settings-section + = render 'shared/web_hooks/title_and_docs', hook: @hook - .col-lg-8.gl-mb-3 + .gl-mb-3 = gitlab_ui_form_for @hook, as: :hook, url: polymorphic_path([@project, :hooks]), html: { class: 'js-webhook-form' } do |f| = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } = f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" } diff --git a/app/views/projects/tags/_edit_release_button.html.haml b/app/views/projects/tags/_edit_release_button.html.haml index 9a6c18df2ca..42af8d4f59f 100644 --- a/app/views/projects/tags/_edit_release_button.html.haml +++ b/app/views/projects/tags/_edit_release_button.html.haml @@ -1,9 +1,8 @@ - release_btn_text = s_('TagsPage|Create release') - release_btn_path = new_project_release_path(project, tag_name: tag.name) - option_css_classes = local_assigns.fetch(:option_css_classes, '') -- css_classes = "btn gl-button btn-default btn-icon btn-edit has-tooltip #{option_css_classes}" - if release - release_btn_text = s_('TagsPage|Edit release') - release_btn_path = edit_project_release_path(project, release) -= link_to release_btn_path, class: css_classes do += render Pajamas::ButtonComponent.new(href: release_btn_path, button_options: { class: option_css_classes }) do = release_btn_text diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml index 986bc53fd81..caaa209a702 100644 --- a/app/views/registrations/welcome/show.html.haml +++ b/app/views/registrations/welcome/show.html.haml @@ -8,6 +8,7 @@ = render "layouts/one_trust" = render "layouts/bizible" = render "layouts/google_tag_manager_body" + .row.gl-flex-grow-1 .d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5 .edit-profile.login-page.d-flex.flex-column.gl-align-items-center diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml index ba968c6b2d2..03300be9181 100644 --- a/app/views/shared/file_hooks/_index.html.haml +++ b/app/views/shared/file_hooks/_index.html.haml @@ -1,15 +1,13 @@ - file_hooks = Gitlab::FileHook.files -.row.gl-mt-3 - .col-lg-4 - %h4.gl-mt-0 - = _('File Hooks') - %p - = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.') - = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks') +.gl-mt-7 + %h4.gl-my-0 + = _('File Hooks') + %p.gl-text-secondary + = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.') + = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks') - - .col-lg-8.gl-mb-3 + .gl-mb-3 - if file_hooks.any? = render Pajamas::CardComponent.new do |c| - c.with_header do diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index 7eafd6ae092..da6ce1652c4 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -3,7 +3,7 @@ .js-vue-webhook-form{ data: webhook_form_data(hook) } .form-group = form.label :token, s_('Webhooks|Secret token'), class: 'label-bold' - = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input' + = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-48' %p.form-text.text-muted - code_start = '<code>'.html_safe - code_end = '</code>'.html_safe diff --git a/app/views/shared/web_hooks/_title_and_docs.html.haml b/app/views/shared/web_hooks/_title_and_docs.html.haml index c220b46f70f..8a6968ee01e 100644 --- a/app/views/shared/web_hooks/_title_and_docs.html.haml +++ b/app/views/shared/web_hooks/_title_and_docs.html.haml @@ -1,10 +1,10 @@ - webhooks_link_start = '<a href="%{url}">'.html_safe % { url: help_page_path(hook.help_path) } -%h4.gl-mt-0 +%h4.gl-my-0 = page_title - if @project - integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path(project: @project) } - %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe } + %p.gl-text-secondary= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe } - else - %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe } + %p.gl-text-secondary= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe } diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml index ce82a5e1614..0b76ed6c086 100644 --- a/app/views/users/_overview.html.haml +++ b/app/views/users/_overview.html.haml @@ -13,12 +13,10 @@ .col-12.col-md-10.col-lg-8.gl-my-6 .gl-display-flex %ol.breadcrumb.gl-breadcrumb-list.gl-mb-4 - %li.breadcrumb-item.gl-breadcrumb-item + %li.gl-breadcrumb-item = link_to project_path(@user.user_project) do = @user.username - %span.gl-breadcrumb-separator - = sprite_icon("chevron-right", size: 16) - %li.breadcrumb-item.gl-breadcrumb-item + %li.gl-breadcrumb-item = link_to @user.user_readme.path, @user.user_project.readme_url - if current_user == @user .gl-ml-auto diff --git a/config/application.rb b/config/application.rb index c8bb56ce956..9c7d8a83560 100644 --- a/config/application.rb +++ b/config/application.rb @@ -217,6 +217,9 @@ module Gitlab sharedSecret ) + # This config option can be removed after Rails 7.1 by https://gitlab.com/gitlab-org/gitlab/-/issues/416270 + config.active_support.use_rfc4122_namespaced_uuids = true + # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true diff --git a/config/feature_flags/development/ai_chat_history_context.yml b/config/feature_flags/development/hide_projects_of_banned_users.yml index cc264093cd5..374782c359a 100644 --- a/config/feature_flags/development/ai_chat_history_context.yml +++ b/config/feature_flags/development/hide_projects_of_banned_users.yml @@ -1,8 +1,8 @@ --- -name: ai_chat_history_context -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122920 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414606 -milestone: '16.1' +name: hide_projects_of_banned_users +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121488 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/412621 +milestone: '16.2' type: development -group: group::ai-enablement +group: group::anti-abuse default_enabled: false diff --git a/config/routes.rb b/config/routes.rb index 3a9b6c1c0bf..740911f2e3f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -246,7 +246,6 @@ InitializerConnections.raise_if_new_database_connection do end get :metrics_dashboard - get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api get :cluster_status, format: :json delete :clear_cache end diff --git a/config/routes/project.rb b/config/routes/project.rb index bf73f461629..d0d14bf80ff 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -29,10 +29,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do # Use this scope for all new project routes. scope '-' do get 'archive/*id', format: true, constraints: { format: Gitlab::PathRegex.archive_formats_regex, id: /.+?/ }, to: 'repositories#archive', as: 'archive' - get 'metrics(/:dashboard_path)', constraints: { dashboard_path: /.+\.yml/ }, - to: 'metrics_dashboard#show', as: :metrics_dashboard, format: false - get 'metrics(/:dashboard_path)/panel/new', constraints: { dashboard_path: /.+\.yml/ }, - to: 'metrics_dashboard#show', as: :new_metrics_dashboard, format: false namespace :metrics, module: :metrics do namespace :dashboards do @@ -330,9 +326,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do post :stop post :cancel_auto_stop get :terminal - get :metrics - get :additional_metrics - get :metrics_dashboard # This route is also defined in gitlab-workhorse. Make sure to update accordingly. get '/terminal.ws/authorize', to: 'environments#terminal_websocket_authorize', format: false @@ -343,7 +336,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do end collection do - get :metrics, action: :metrics_redirect get :folder, path: 'folders/*id', constraints: { format: /(html|json)/ } get :search end diff --git a/data/deprecations/15-9-accessibility-testing-deprecation.yml b/data/deprecations/15-9-accessibility-testing-deprecation.yml deleted file mode 100644 index 74fb61ed2fc..00000000000 --- a/data/deprecations/15-9-accessibility-testing-deprecation.yml +++ /dev/null @@ -1,26 +0,0 @@ -# -# REQUIRED FIELDS -# -- title: "Accessibility Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters." - announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated. - removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed - breaking_change: true # (required) Change to false if this is not a breaking change. - reporter: jocelynjane # (required) GitLab username of the person reporting the change - stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth - issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390424 # (required) Link to the deprecation issue in GitLab - body: | # (required) Do not modify this line, instead modify the lines below. - Due to low customer usage, Accessibility Testing is deprecated and will be removed. There is no planned replacement and users should stop using Accessibility Testing before GitLab 17.0. -# -# OPTIONAL END OF SUPPORT FIELDS -# -# If an End of Support period applies, the announcement should be shared with GitLab Support -# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR. -# - end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end. - # - # OTHER OPTIONAL FIELDS - # - tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] - documentation_url: https://docs.gitlab.com/ee/ci/testing/accessibility_testing.html # (optional) This is a link to the current documentation page - image_url: # (optional) This is a link to a thumbnail image depicting the feature - video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg diff --git a/data/deprecations/15-9-browser-performance-testing-deprecation.yml b/data/deprecations/15-9-browser-performance-testing-deprecation.yml deleted file mode 100644 index a5d7429b56b..00000000000 --- a/data/deprecations/15-9-browser-performance-testing-deprecation.yml +++ /dev/null @@ -1,26 +0,0 @@ -# -# REQUIRED FIELDS -# -- title: "Browser Performance Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters." - announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated. - removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed - breaking_change: true # (required) Change to false if this is not a breaking change. - reporter: jocelynjane # (required) GitLab username of the person reporting the change - stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth - issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388719 # (required) Link to the deprecation issue in GitLab - body: | # (required) Do not modify this line, instead modify the lines below. - Due to limited customer usage, Browser Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Browser Performance Testing before GitLab 17.0. -# -# OPTIONAL END OF SUPPORT FIELDS -# -# If an End of Support period applies, the announcement should be shared with GitLab Support -# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR. -# - end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end. - # - # OTHER OPTIONAL FIELDS - # - tiers: Premium # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] - documentation_url: https://docs.gitlab.com/ee/ci/testing/browser_performance_testing.html # (optional) This is a link to the current documentation page - image_url: # (optional) This is a link to a thumbnail image depicting the feature - video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg diff --git a/data/deprecations/15-9-load-performance-testing-deprecation.yml b/data/deprecations/15-9-load-performance-testing-deprecation.yml deleted file mode 100644 index 77b56c69f92..00000000000 --- a/data/deprecations/15-9-load-performance-testing-deprecation.yml +++ /dev/null @@ -1,26 +0,0 @@ -# -# REQUIRED FIELDS -# -- title: "Load Performance Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters." - announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated. - removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed - breaking_change: true # (required) Change to false if this is not a breaking change. - reporter: jocelynjane # (required) GitLab username of the person reporting the change - stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth - issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388723 # (required) Link to the deprecation issue in GitLab - body: | # (required) Do not modify this line, instead modify the lines below. - Due to low customer usage, Load Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Load Performance Testing before GitLab 17.0. -# -# OPTIONAL END OF SUPPORT FIELDS -# -# If an End of Support period applies, the announcement should be shared with GitLab Support -# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR. -# - end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end. - # - # OTHER OPTIONAL FIELDS - # - tiers: Premium # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] - documentation_url: https://docs.gitlab.com/ee/ci/testing/load_performance_testing.html # (optional) This is a link to the current documentation page - image_url: # (optional) This is a link to a thumbnail image depicting the feature - video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg diff --git a/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb b/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb new file mode 100644 index 00000000000..209a2295f22 --- /dev/null +++ b/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class CreateIndexForVulnerabilityReadsOnCommonProjectFilters < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + INDEX_NAME = 'index_project_vulnerability_reads_common_finder_query_desc' + + def up + add_concurrent_index :vulnerability_reads, + [:project_id, :state, :report_type, :severity, :vulnerability_id], + order: { severity: :desc, vulnerability_id: :desc }, + name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :vulnerability_reads, INDEX_NAME + end +end diff --git a/db/schema_migrations/20230626101519 b/db/schema_migrations/20230626101519 new file mode 100644 index 00000000000..874d3eec0ee --- /dev/null +++ b/db/schema_migrations/20230626101519 @@ -0,0 +1 @@ +7060d1ed7be6fce2e398d9ac042d6e67826742e639df8eee43245d66b8b87ea3
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 7368b3a76de..09709075788 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -32410,6 +32410,8 @@ CREATE INDEX index_project_topics_on_topic_id ON project_topics USING btree (top CREATE UNIQUE INDEX index_project_user_callouts_feature ON user_project_callouts USING btree (user_id, feature_name, project_id); +CREATE INDEX index_project_vulnerability_reads_common_finder_query_desc ON vulnerability_reads USING btree (project_id, state, report_type, severity DESC, vulnerability_id DESC); + CREATE UNIQUE INDEX index_project_wiki_repositories_on_project_id ON project_wiki_repositories USING btree (project_id); CREATE INDEX index_projects_aimed_for_deletion ON projects USING btree (marked_for_deletion_at) WHERE ((marked_for_deletion_at IS NOT NULL) AND (pending_delete = false)); diff --git a/doc/api/groups.md b/doc/api/groups.md index 7b73fe9066e..fb645036dc0 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -303,6 +303,7 @@ Parameters: | `simple` | boolean | no | Return only limited fields for each project. This is a no-op without authentication where only simple fields are returned. | | `owned` | boolean | no | Limit by projects owned by the current user | | `starred` | boolean | no | Limit by projects starred by the current user | +| `topic` | string | no | Return projects matching the topic | | `with_issues_enabled` | boolean | no | Limit by projects with issues feature enabled. Default is `false` | | `with_merge_requests_enabled` | boolean | no | Limit by projects with merge requests feature enabled. Default is `false` | | `with_shared` | boolean | no | Include projects shared to this group. Default is `true` | diff --git a/doc/api/users.md b/doc/api/users.md index ed788600e62..d96dd99c18e 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -510,7 +510,7 @@ Parameters: | `auditor` **(PREMIUM)** | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3. | | `avatar` | No | Image file for user's avatar | | `bio` | No | User's biography | -| `can_create_group` | No | User can create groups - true or false | +| `can_create_group` | No | User can create top-level groups - true or false | | `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#syntax-highlighting-theme)) | | `email` | Yes | Email | | `extern_uid` | No | External UID | diff --git a/doc/architecture/blueprints/gitlab_ci_events/index.md b/doc/architecture/blueprints/gitlab_ci_events/index.md index 7ce8fea9410..aab3a54cbd2 100644 --- a/doc/architecture/blueprints/gitlab_ci_events/index.md +++ b/doc/architecture/blueprints/gitlab_ci_events/index.md @@ -2,6 +2,7 @@ status: proposed creation-date: "2023-03-15" authors: [ "@furkanayhan" ] +owners: [ "@furkanayhan" ] coach: "@grzesiek" approvers: [ "@jreporter", "@cheryl.li" ] owning-stage: "~devops::verify" diff --git a/doc/development/value_stream_analytics.md b/doc/development/value_stream_analytics.md index e056ce9b064..30244407e38 100644 --- a/doc/development/value_stream_analytics.md +++ b/doc/development/value_stream_analytics.md @@ -41,8 +41,8 @@ feature-full. |Total time chart|Yes|No|No| |Task by type chart|Yes|No|No| |DORA Metrics|Yes|Yes|No| -|Cycle time and lead time summary (Key metrics)|Yes|Yes|No| -|New issues, commits and deploys (Key metrics)|Yes, excluding commits|Yes|Yes| +|Cycle time and lead time summary (Lifecycle metrics)|Yes|Yes|No| +|New issues, commits and deploys (Lifecycle metrics)|Yes, excluding commits|Yes|Yes| |Uses aggregated backend|Yes|No|No| |Date filter behavior|Filters items [finished within the date range](https://gitlab.com/groups/gitlab-org/-/epics/6046)|Filters items by creation date.|Filters items by creation date.| |Authorization|At least reporter|At least reporter|Can be public.| diff --git a/doc/tutorials/left_sidebar/index.md b/doc/tutorials/left_sidebar/index.md index f26849eac45..80fbbf2032e 100644 --- a/doc/tutorials/left_sidebar/index.md +++ b/doc/tutorials/left_sidebar/index.md @@ -63,7 +63,7 @@ To start, we will find the project we want to work on. ![Project-specific options](img/project_selected_v16_0.png) -## Customize the sidebar +## Pin frequently used items You can pin menu items if you tend to use them frequently. @@ -76,6 +76,9 @@ The item is displayed in the **Pinned** section: ![pinned item](img/pinned_v16_0.png) +NOTE: +The items you pin while you're viewing a project are different than the items you pin while viewing a group. + ## Use a more focused view On the left sidebar, you can also choose a more focused view into the areas you have access to. diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index 58c610048cd..a468fff5fec 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -50,20 +50,6 @@ For deprecation reviewers (Technical Writers only): <div class="deprecation breaking-change" data-milestone="17.0"> -### Accessibility Testing is deprecated - -<div class="deprecation-notes"> -- Announced in: GitLab <span class="milestone">15.9</span> -- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change). -- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390424). -</div> - -Due to low customer usage, Accessibility Testing is deprecated and will be removed. There is no planned replacement and users should stop using Accessibility Testing before GitLab 17.0. - -</div> - -<div class="deprecation breaking-change" data-milestone="17.0"> - ### Atlassian Crowd OmniAuth provider <div class="deprecation-notes"> @@ -97,20 +83,6 @@ Because Cloud Native Buildpacks do not support automatic testing, the Auto Test <div class="deprecation breaking-change" data-milestone="17.0"> -### Browser Performance Testing is deprecated - -<div class="deprecation-notes"> -- Announced in: GitLab <span class="milestone">15.9</span> -- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change). -- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388719). -</div> - -Due to limited customer usage, Browser Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Browser Performance Testing before GitLab 17.0. - -</div> - -<div class="deprecation breaking-change" data-milestone="17.0"> - ### CiRunner.projects default sort is changing to `id_desc` <div class="deprecation-notes"> @@ -333,20 +305,6 @@ In GitLab 17.0, the `DISABLED_WITH_OVERRIDE` value of the `SharedRunnersSetting` <div class="deprecation breaking-change" data-milestone="17.0"> -### Load Performance Testing is deprecated - -<div class="deprecation-notes"> -- Announced in: GitLab <span class="milestone">15.9</span> -- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change). -- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388723). -</div> - -Due to low customer usage, Load Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Load Performance Testing before GitLab 17.0. - -</div> - -<div class="deprecation breaking-change" data-milestone="17.0"> - ### Maintainer role providing the ability to change Package settings using GraphQL API <div class="deprecation-notes"> diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md index fd08c58cbcd..f98f1a874c4 100644 --- a/doc/user/admin_area/moderate_users.md +++ b/doc/user/admin_area/moderate_users.md @@ -256,8 +256,9 @@ Users can also be activated using the [GitLab API](../../api/users.md#activate-u > - Ban and unban users [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/327353) in GitLab 14.8. Feature flag `ban_user_feature_flag` removed. > - Hiding merge requests of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107836) in GitLab 15.8 [with a flag](../../administration/feature_flags.md) named `hide_merge_requests_from_banned_users`. Disabled by default. > - Hiding comments of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112973) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `hidden_notes`. Disabled by default. +> - Hiding projects of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121488) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `hide_projects_of_banned_users`. Disabled by default. -GitLab administrators can ban and unban users. Banned users are blocked, and their issues, merge requests, and comments are hidden. +GitLab administrators can ban and unban users. Banned users are blocked, and their projects, issues, merge requests, and comments are hidden. ### Ban a user diff --git a/doc/user/analytics/value_streams_dashboard.md b/doc/user/analytics/value_streams_dashboard.md index 9b332d78060..2e40be2a43d 100644 --- a/doc/user/analytics/value_streams_dashboard.md +++ b/doc/user/analytics/value_streams_dashboard.md @@ -57,7 +57,7 @@ To view the value streams dashboard: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group. 1. Select **Analyze > Value stream analytics**. -1. Below the **Filter results** text box, in the **Key metrics** row, select **Value Streams Dashboard / DORA**. +1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**. 1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL (for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`). @@ -142,8 +142,8 @@ panels: | Lead time for changes | The time to successfully deliver a commit into production. This metric reflects the efficiency of CI/CD pipelines. | [Lead time tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=lead-time) | [Lead time for changes](dora_metrics.md#lead-time-for-changes) | `lead_time_for_changes` | | Time to restore service | The time it takes an organization to recover from a failure in production. | [Time to restore service tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=time-to-restore-service) | [Time to restore service](dora_metrics.md#time-to-restore-service) | `time_to_restore_service` | | Change failure rate | Percentage of deployments that cause an incident in production. | [Change failure rate tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=change-failure-rate) | [Change failure rate](dora_metrics.md#change-failure-rate) | `change_failure_rate` | -| Lead time | Median time from issue created to issue closed. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#key-metrics) | `lead_time` | -| Cycle time | Median time from the earliest commit of a linked issue's merge request to when that issue is closed. | [VSA overview](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#key-metrics) | `cycle_time` | +| Lead time | Median time from issue created to issue closed. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#lifecycle-metrics) | `lead_time` | +| Cycle time | Median time from the earliest commit of a linked issue's merge request to when that issue is closed. | [VSA overview](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#lifecycle-metrics) | `cycle_time` | | New issues | Number of new issues created. | [Issue Analytics](https://gitlab.com/groups/gitlab-org/-/issues_analytics) | Issue analytics [for projects](issue_analytics.md) and [for groups](../../user/group/issues_analytics/index.md) | `issues` | | Closed issues | Number of issues closed by month. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [Value Stream Analytics](../group/value_stream_analytics/index.md) | `issues_completed` | | Number of deploys | Total number of deploys to production. | [Merge Request Analytics](https://gitlab.com/gitlab-org/gitlab/-/analytics/merge_request_analytics) | [Merge request analytics](merge_request_analytics.md) | `deploys` | diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md index 5838b9821de..8cc261af50d 100644 --- a/doc/user/group/saml_sso/index.md +++ b/doc/user/group/saml_sso/index.md @@ -396,11 +396,10 @@ convert the information to XML. An example SAML response is shown here. By default, users provisioned with SAML or SCIM are sent a verification email to verify their identity. Instead, you can [configure GitLab with a custom domain](../../enterprise_user/index.md#set-up-a-verified-domain) and GitLab automatically confirms user accounts. Users still receive an -[enterprise user](../../enterprise_user/index.md) welcome email. Confirmation is -bypassed for users: +[enterprise user](../../enterprise_user/index.md) welcome email. Confirmation is bypassed if both of the following are true: -- That are provisioned with SAML or SCIM. -- That have an email address that belongs to the verified domain. +- The user is provisioned with SAML or SCIM. +- The user has an email address that belongs to the verified domain. ### Block user access diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md index 952552fc648..dba7a507fef 100644 --- a/doc/user/group/value_stream_analytics/index.md +++ b/doc/user/group/value_stream_analytics/index.md @@ -45,8 +45,8 @@ Value stream analytics offers different features at the project and group level |Total time chart|Yes|Yes|No| |Task by type chart|Yes|No|No| |DORA Metrics|Yes|Yes|No| -|Cycle time and lead time summary (Key metrics)|Yes|Yes|No| -|New issues, commits, and deploys (Key metrics)|Yes, excluding commits|Yes|Yes| +|Cycle time and lead time summary (Lifecycle metrics)|Yes|Yes|No| +|New issues, commits, and deploys (Lifecycle metrics)|Yes, excluding commits|Yes|Yes| |Uses aggregated backend|Yes|Yes|No| |Date filter behavior|Filters items [finished within the date range](https://gitlab.com/groups/gitlab-org/-/epics/6046)|Filters items by creation date.|Filters items by creation date.| |Authorization|At least reporter|At least reporter|Can be public| @@ -253,9 +253,9 @@ For the "Tasks by type" chart, only the Date range and Project selector filters The **Overview** page in value stream analytics displays key metrics of the DevSecOps lifecycle performance for projects and groups. -### Key metrics +### Lifecycle metrics -Value stream analytics includes the following key metrics: +Value stream analytics includes the following lifecycle metrics: - **Lead time**: Median time from when the issue was created to when it was closed. - **Cycle time**: Median time from first commit to issue closed. GitLab measures cycle time from the earliest commit of a @@ -290,21 +290,21 @@ NOTE: In GitLab 13.9 and later, deployment frequency metrics are calculated based on when the deployment was finished. In GitLab 13.8 and earlier, deployment frequency metrics are calculated based on when the deployment was created. -## View key and DORA metrics +## View lifecycle and DORA metrics Prerequisite: - To view deployment metrics, you must have a [production environment configured](#how-value-stream-analytics-identifies-the-production-environment). -To view key lifecycle metrics: +To view lifecycle metrics: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group. 1. Select **Analyze > Value stream analytics**. - Key metrics display below the **Filter results** text box. + Lifecycle metrics display below the **Filter results** text box. 1. Optional. Filter the results: 1. Select the **Filter results** text box. - Based on the filter you select, the dashboard automatically aggregates key metrics and displays the status of the value stream. + Based on the filter you select, the dashboard automatically aggregates lifecycle metrics and displays the status of the value stream. 1. Select a parameter. 1. Select a value or enter text to refine the results. 1. To adjust the date range: @@ -315,7 +315,7 @@ To view the [Value Streams Dashboard](../../analytics/value_streams_dashboard.md 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group. 1. Select **Analyze > Value stream analytics**. -1. Below the **Filter results** text box, in the **Key metrics** row, select **Value Streams Dashboard / DORA**. +1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**. 1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL (for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`). diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md index 1aef5bd3040..08613408f7d 100644 --- a/doc/user/project/pages/introduction.md +++ b/doc/user/project/pages/introduction.md @@ -95,12 +95,7 @@ you can create your project first and access it under `http(s)://namespace.examp ## Enable unique domains > - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/9347) in GitLab 15.9 [with a flag](../../../administration/feature_flags.md) named `pages_unique_domain`. Disabled by default. -> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/388151) in GitLab 15.11. - -FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, -ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `pages_unique_domain`. -On GitLab.com, by default this feature is available. +> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/388151) in GitLab 15.11. By default, every project in a group shares the same domain, for example, `group.gitlab.io`. This means that cookies are also shared for all projects in a group. diff --git a/lib/api/helpers/custom_attributes.rb b/lib/api/helpers/custom_attributes.rb index 88208226c40..fc3f42f0d58 100644 --- a/lib/api/helpers/custom_attributes.rb +++ b/lib/api/helpers/custom_attributes.rb @@ -8,7 +8,7 @@ module API included do helpers do params :with_custom_attributes do - optional :with_custom_attributes, type: Boolean, default: false, desc: 'Include custom attributes in the response' + optional :with_custom_attributes, type: ::Grape::API::Boolean, default: false, desc: 'Include custom attributes in the response' optional :custom_attributes, type: Hash, desc: 'Filter with custom attributes' diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb index 850cc61af2c..09dd69ef03b 100644 --- a/lib/api/helpers/integrations_helpers.rb +++ b/lib/api/helpers/integrations_helpers.rb @@ -41,7 +41,7 @@ module API { required: false, name: :notify_only_broken_pipelines, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Send notifications for broken pipelines' } ].freeze @@ -129,85 +129,85 @@ module API { required: false, name: :commit_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for commit_events' }, { required: false, name: :push_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for push_events' }, { required: false, name: :issues_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for issues_events' }, { required: false, name: :incident_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for incident_events' }, { required: false, name: :alert_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for alert_events' }, { required: false, name: :confidential_issues_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for confidential_issues_events' }, { required: false, name: :merge_requests_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for merge_requests_events' }, { required: false, name: :note_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for note_events' }, { required: false, name: :confidential_note_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for confidential_note_events' }, { required: false, name: :tag_push_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for tag_push_events' }, { required: false, name: :deployment_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for deployment_events' }, { required: false, name: :job_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for job_events' }, { required: false, name: :pipeline_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for pipeline_events' }, { required: false, name: :wiki_page_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable notifications for wiki_page_events' } ].freeze @@ -243,7 +243,7 @@ module API { required: false, name: :app_store_protected_refs, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Only enable for protected refs' } ], @@ -285,7 +285,7 @@ module API { required: false, name: :enable_ssl_verification, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable SSL verification' }, { @@ -343,7 +343,7 @@ module API { required: false, name: :enable_ssl_verification, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'DEPRECATED: This parameter has no effect since SSL verification will always be enabled' } ], @@ -417,7 +417,7 @@ module API { required: false, name: :archive_trace_events, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'When enabled, job logs will be collected by Datadog and shown along pipeline execution traces' }, { @@ -471,7 +471,7 @@ module API { required: false, name: :enable_ssl_verification, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable SSL verification' } ], @@ -485,13 +485,13 @@ module API { required: false, name: :disable_diffs, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Disable code diffs' }, { required: false, name: :send_from_committer_email, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Send from committer' }, { @@ -598,7 +598,7 @@ module API { required: false, name: :colorize_messages, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Colorize messages' } ], @@ -612,7 +612,7 @@ module API { required: false, name: :enable_ssl_verification, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable SSL verification' }, { @@ -668,7 +668,7 @@ module API { required: false, name: :jira_issue_transition_automatic, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable automatic issue transitions' }, { @@ -692,7 +692,7 @@ module API { required: false, name: :comment_on_event_enabled, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable comments inside Jira issues on each GitLab event (commit / merge request)' } ], @@ -750,13 +750,13 @@ module API { required: false, name: :notify_only_broken_pipelines, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Notify only broken pipelines' }, { required: false, name: :notify_only_default_branch, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Send notifications only for the default branch' }, { @@ -946,7 +946,7 @@ module API { required: false, name: :enable_ssl_verification, - type: Boolean, + type: ::Grape::API::Boolean, desc: 'Enable SSL verification' }, { diff --git a/lib/gitlab/alert_management/payload/prometheus.rb b/lib/gitlab/alert_management/payload/prometheus.rb index 76f3da8366b..cf6fe449398 100644 --- a/lib/gitlab/alert_management/payload/prometheus.rb +++ b/lib/gitlab/alert_management/payload/prometheus.rb @@ -78,18 +78,6 @@ module Gitlab rescue URI::InvalidURIError, KeyError end - def metrics_dashboard_url - return unless environment && full_query && title - - metrics_dashboard_project_environment_url( - project, - environment, - embed_json: dashboard_json, - embedded: true, - **alert_embed_window_params - ) - end - def has_required_attributes? project && title && starts_at_raw end diff --git a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb index 31d75225972..56a82d1df46 100644 --- a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb +++ b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb @@ -7,59 +7,14 @@ module Gitlab class ClusterEndpointInserter < BaseStage def transform! verify_params - - for_metrics do |metric| - metric[:prometheus_endpoint_path] = endpoint_for_metric(metric) - end end private - def admin_url(metric) - Gitlab::Routing.url_helpers.prometheus_api_admin_cluster_path( - params[:cluster], - proxy_path: query_type(metric), - query: query_for_metric(metric) - ) - end - - def endpoint_for_metric(metric) - case params[:cluster_type] - when :admin - admin_url(metric) - when :group - error!(_('Group is required when cluster_type is :group')) unless params[:group] - group_url(metric) - when :project - error!(_('Project is required when cluster_type is :project')) unless project - project_url(metric) - else - error!(_('Unrecognized cluster type')) - end - end - def error!(message) raise Errors::DashboardProcessingError, message end - def group_url(metric) - Gitlab::Routing.url_helpers.prometheus_api_group_cluster_path( - params[:group], - params[:cluster], - proxy_path: query_type(metric), - query: query_for_metric(metric) - ) - end - - def project_url(metric) - Gitlab::Routing.url_helpers.prometheus_api_project_cluster_path( - project, - params[:cluster], - proxy_path: query_type(metric), - query: query_for_metric(metric) - ) - end - def query_type(metric) metric[:query] ? :query : :query_range end diff --git a/lib/gitlab/metrics/dashboard/url.rb b/lib/gitlab/metrics/dashboard/url.rb index bdd28744137..e7b901861ef 100644 --- a/lib/gitlab/metrics/dashboard/url.rb +++ b/lib/gitlab/metrics/dashboard/url.rb @@ -12,26 +12,6 @@ module Gitlab ANCHOR_PATTERN = '(?<anchor>\#[a-z0-9_-]+)?' DASH_PATTERN = '(?:/-)' - # Matches urls for a metrics dashboard. - # This regex needs to match the old metrics URL, the new metrics URL, - # and the dashboard URL (inline_metrics_redactor_filter.rb - # uses this regex to match against the dashboard URL.) - # - # EX - Old URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics - # OR - # New URL: https://<host>/<namespace>/<project>/-/metrics?environment=<env_id> - # OR - # dashboard URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics_dashboard - def metrics_regex - strong_memoize(:metrics_regex) do - regex_for_project_metrics( - %r{ - ( #{environment_metrics_regex} ) | ( #{non_environment_metrics_regex} ) - }x - ) - end - end - # Matches dashboard urls for a Grafana embed. # # EX - https://<host>/<namespace>/<project>/grafana/metrics_dashboard @@ -99,11 +79,6 @@ module Gitlab .symbolize_keys end - # Builds a metrics dashboard url based on the passed in arguments - def build_dashboard_url(...) - Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_environment_url(...) - end - private def environment_metrics_regex diff --git a/lib/gitlab/uuid.rb b/lib/gitlab/uuid.rb index 016c25eb94b..a3abe90a412 100644 --- a/lib/gitlab/uuid.rb +++ b/lib/gitlab/uuid.rb @@ -10,8 +10,6 @@ module Gitlab }.freeze UUID_V5_PATTERN = /\h{8}-\h{4}-5\h{3}-\h{4}-\h{12}/.freeze - NAMESPACE_REGEX = /(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/.freeze - PACK_PATTERN = "NnnnnN" class << self def v5(name, namespace_id: default_namespace_id) @@ -25,12 +23,7 @@ module Gitlab private def default_namespace_id - @default_namespace_id ||= begin - namespace_uuid = NAMESPACE_IDS.fetch(Rails.env.to_sym) - # Digest::UUID is broken when using a UUID as a namespace_id - # https://github.com/rails/rails/issues/37681#issue-520718028 - namespace_uuid.scan(NAMESPACE_REGEX).flatten.map { |s| s.to_i(16) }.pack(PACK_PATTERN) - end + NAMESPACE_IDS.fetch(Rails.env.to_sym) end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 1fcf4cc719e..27e654115cb 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -99,6 +99,16 @@ msgid_plural "%d Approvals" msgstr[0] "" msgstr[1] "" +msgid "%d Issue" +msgid_plural "%d Issues" +msgstr[0] "" +msgstr[1] "" + +msgid "%d Merge Request" +msgid_plural "%d Merge Requests" +msgstr[0] "" +msgstr[1] "" + msgid "%d Module" msgid_plural "%d Modules" msgstr[0] "" @@ -354,16 +364,6 @@ msgid_plural "%d more comments" msgstr[0] "" msgstr[1] "" -msgid "%d opened Issue" -msgid_plural "%d opened Issues" -msgstr[0] "" -msgstr[1] "" - -msgid "%d opened Merge Request" -msgid_plural "%d opened Merge Requests" -msgstr[0] "" -msgstr[1] "" - msgid "%d package" msgid_plural "%d packages" msgstr[0] "" @@ -3867,9 +3867,6 @@ msgstr "" msgid "AdminUsers|Is using seat" msgstr "" -msgid "AdminUsers|Issues and merge requests authored by this user are hidden from other users." -msgstr "" - msgid "AdminUsers|It's you!" msgstr "" @@ -3915,6 +3912,9 @@ msgstr "" msgid "AdminUsers|Private profile" msgstr "" +msgid "AdminUsers|Projects, issues, merge requests, and comments of this user are hidden from other users." +msgstr "" + msgid "AdminUsers|Reactivating a user will:" msgstr "" @@ -21478,9 +21478,6 @@ msgstr "" msgid "Group information" msgstr "" -msgid "Group is required when cluster_type is :group" -msgstr "" - msgid "Group jobs by" msgstr "" @@ -35653,9 +35650,6 @@ msgstr "" msgid "Project information" msgstr "" -msgid "Project is required when cluster_type is :project" -msgstr "" - msgid "Project members" msgstr "" @@ -42002,6 +41996,9 @@ msgstr "" msgid "SecurityReports|There was an error adding the comment." msgstr "" +msgid "SecurityReports|There was an error creating a Jira issue for the finding. Please try again." +msgstr "" + msgid "SecurityReports|There was an error creating the issue." msgstr "" @@ -48937,9 +48934,6 @@ msgstr "" msgid "Unrecognized approval status." msgstr "" -msgid "Unrecognized cluster type" -msgstr "" - msgid "Unresolve" msgstr "" @@ -50193,7 +50187,7 @@ msgstr "" msgid "ValueStreamAnalytics|High vulnerabilities over time." msgstr "" -msgid "ValueStreamAnalytics|Key metrics" +msgid "ValueStreamAnalytics|Lifecycle metrics" msgstr "" msgid "ValueStreamAnalytics|Median time an incident was open on a production environment in the given time period." @@ -50506,9 +50500,6 @@ msgstr "" msgid "View page @ " msgstr "" -msgid "View performance dashboard." -msgstr "" - msgid "View project in admin area" msgstr "" @@ -50538,9 +50529,6 @@ msgstr "" msgid "View the latest successful deployment to this environment" msgstr "" -msgid "View the performance dashboard at" -msgstr "" - msgid "View usage details" msgstr "" diff --git a/rubocop/formatter/todo_formatter.rb b/rubocop/formatter/todo_formatter.rb index 912ce0da2cc..9e20a95ba85 100644 --- a/rubocop/formatter/todo_formatter.rb +++ b/rubocop/formatter/todo_formatter.rb @@ -23,8 +23,8 @@ module RuboCop # with offenses. # # See https://gitlab.com/gitlab-org/gitlab/-/issues/415330#caveats - # on why the entry must end with `.html.haml.rb`. - RETAIN_EXCLUSIONS = %r{\.html\.haml\.rb$} + # on why the entry must end with `.haml.rb`. + RETAIN_EXCLUSIONS = %r{\.haml\.rb$} class << self attr_accessor :base_directory diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index bface886674..15b7ddd85ea 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -113,18 +113,6 @@ RSpec.describe Projects::ClustersController, feature_category: :deployment_manag end end - it_behaves_like 'GET #metrics_dashboard for dashboard', 'Cluster health' do - let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } - - let(:metrics_dashboard_req_params) do - { - id: cluster.id, - namespace_id: project.namespace.full_path, - project_id: project.path - } - end - end - describe 'POST create for existing cluster' do let(:params) do { diff --git a/spec/factories/project_authorizations.rb b/spec/factories/project_authorizations.rb index ffdf5576f84..1726da55c99 100644 --- a/spec/factories/project_authorizations.rb +++ b/spec/factories/project_authorizations.rb @@ -6,4 +6,8 @@ FactoryBot.define do project access_level { Gitlab::Access::REPORTER } end + + trait :owner do + access_level { Gitlab::Access::OWNER } + end end diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index 3d108951c64..a795df4dec6 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ProjectsFinder do +RSpec.describe ProjectsFinder, feature_category: :groups_and_projects do include AdminModeHelper describe '#execute' do @@ -25,6 +25,12 @@ RSpec.describe ProjectsFinder do create(:project, :private, name: 'D', path: 'D') end + let_it_be(:banned_user_project) do + create(:project, :public, name: 'Project created by a banned user', creator: create(:user, :banned)).tap do |p| + create(:project_authorization, :owner, user: p.creator, project: p) + end + end + let(:params) { {} } let(:current_user) { user } let(:project_ids_relation) { nil } @@ -488,16 +494,32 @@ RSpec.describe ProjectsFinder do describe 'with admin user' do let(:user) { create(:admin) } - context 'admin mode enabled' do + context 'with admin mode enabled' do before do enable_admin_mode!(current_user) end - it { is_expected.to match_array([public_project, internal_project, private_project, shared_project]) } + it do + is_expected.to match_array([ + public_project, + internal_project, + private_project, + shared_project, + banned_user_project + ]) + end end - context 'admin mode disabled' do + context 'with admin mode disabled' do it { is_expected.to match_array([public_project, internal_project]) } + + context 'when hide_projects_of_banned_users FF is disabled' do + before do + stub_feature_flags(hide_projects_of_banned_users: false) + end + + it { is_expected.to match_array([public_project, internal_project, banned_user_project]) } + end end end end diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json index 8ee207b7ebf..79132c0d039 100644 --- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json +++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json @@ -2,23 +2,57 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": [ - "label", - "prometheus_endpoint_path" + "label" ], "oneOf": [ - { "required": ["query"] }, - { "required": ["query_range"] } + { + "required": [ + "query" + ] + }, + { + "required": [ + "query_range" + ] + } ], "properties": { - "id": { "type": "string" }, - "query_range": { "type": ["string", "number"] }, - "query": { "type": ["string", "number"] }, - "unit": { "type": "string" }, - "label": { "type": "string" }, - "track": { "type": "string" }, - "prometheus_endpoint_path": { "type": "string" }, - "metric_id": { "type": "number" }, - "edit_path": { "type": ["string", "null"] } + "id": { + "type": "string" + }, + "query_range": { + "type": [ + "string", + "number" + ] + }, + "query": { + "type": [ + "string", + "number" + ] + }, + "unit": { + "type": "string" + }, + "label": { + "type": "string" + }, + "track": { + "type": "string" + }, + "prometheus_endpoint_path": { + "type": "string" + }, + "metric_id": { + "type": "number" + }, + "edit_path": { + "type": [ + "string", + "null" + ] + } }, "additionalProperties": false } diff --git a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js index 9d34d9d0e9e..ee3ad59bf9a 100644 --- a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js +++ b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js @@ -1,4 +1,4 @@ -import { GlDropdownItem, GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui'; +import { GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import SuggestionsDropdown from '~/content_editor/components/suggestions_dropdown.vue'; @@ -113,7 +113,7 @@ describe('~/content_editor/components/suggestions_dropdown', () => { ${'emoji'} | ${'emoji'} | ${':'} | ${exampleEmoji} | ${`😃`} | ${insertedEmojiProps} `( 'runs a command to insert the selected $referenceType', - ({ char, nodeType, referenceType, reference, insertedText, insertedProps }) => { + async ({ char, nodeType, referenceType, reference, insertedText, insertedProps }) => { const commandSpy = jest.fn(); buildWrapper({ @@ -129,7 +129,10 @@ describe('~/content_editor/components/suggestions_dropdown', () => { }, }); - wrapper.findComponent(GlDropdownItem).vm.$emit('click'); + await wrapper + .findByTestId('content-editor-suggestions-dropdown') + .find('li .gl-new-dropdown-item-content') + .trigger('click'); expect(commandSpy).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap index 3b4554700b4..b1eb666b5fd 100644 --- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap +++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap @@ -5,8 +5,6 @@ exports[`Dashboard template matches the default snapshot 1`] = ` class="prometheus-graphs" data-testid="prometheus-graphs" environmentstate="available" - metricsdashboardbasepath="/monitoring/monitor-project/-/metrics?environment=1" - metricsendpoint="/monitoring/monitor-project/-/environments/1/additional_metrics.json" > <div> <gl-alert-stub diff --git a/spec/frontend/pages/groups/new/components/app_spec.js b/spec/frontend/pages/groups/new/components/app_spec.js index 19240f1a044..baf0ca2beca 100644 --- a/spec/frontend/pages/groups/new/components/app_spec.js +++ b/spec/frontend/pages/groups/new/components/app_spec.js @@ -1,4 +1,7 @@ import { shallowMount } from '@vue/test-utils'; +import GROUP_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/group-import.svg?url'; +import GROUP_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/group-new.svg?url'; + import App from '~/pages/groups/new/components/app.vue'; import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue'; @@ -27,6 +30,7 @@ describe('App component', () => { { href: '#', text: 'New group' }, ]); expect(findCreateGroupPanel().title).toBe('Create group'); + expect(findCreateGroupPanel().imageSrc).toBe(GROUP_NEW_SVG_URL); }); it('creates correct component for subgroup creation', () => { @@ -45,5 +49,6 @@ describe('App component', () => { ]); expect(findCreateGroupPanel().title).toBe('Create subgroup'); expect(findCreateGroupPanel().detailProps).toEqual(detailProps); + expect(findCreateGroupPanel().imageSrc).toBe(GROUP_IMPORT_SVG_URL); }); }); diff --git a/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap b/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap new file mode 100644 index 00000000000..0c4d63c3509 --- /dev/null +++ b/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Experimental new project creation app creates correct panels 1`] = ` +Array [ + Object { + "description": "Create a blank project to store your files, plan your work, and collaborate on code, among other things.", + "imageSrc": "file-mock", + "key": "blank", + "name": "blank_project", + "selector": "#blank-project-pane", + "title": "Create blank project", + }, + Object { + "description": "Create a project pre-populated with the necessary files to get you started quickly.", + "imageSrc": "file-mock", + "key": "template", + "name": "create_from_template", + "selector": "#create-from-template-pane", + "title": "Create from template", + }, + Object { + "description": "Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.", + "imageSrc": "file-mock", + "key": "import", + "name": "import_project", + "selector": "#import-project-pane", + "title": "Import project", + }, +] +`; diff --git a/spec/frontend/projects/new/components/app_spec.js b/spec/frontend/projects/new/components/app_spec.js index 60d8385eb91..006114e7254 100644 --- a/spec/frontend/projects/new/components/app_spec.js +++ b/spec/frontend/projects/new/components/app_spec.js @@ -23,6 +23,12 @@ describe('Experimental new project creation app', () => { expect(wrapper.find(guidelineSelector).text()).toBe(DEMO_GUIDELINES); }); + it('creates correct panels', () => { + createComponent(); + + expect(findNewNamespacePage().props('panels')).toMatchSnapshot(); + }); + it.each` isCiCdAvailable | outcome ${false} | ${'do not show CI/CD panel'} diff --git a/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js b/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js index cc8a8d86d19..3306e316ed0 100644 --- a/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js +++ b/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js @@ -39,6 +39,18 @@ describe('Welcome page', () => { expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_tab', { label: 'test' }); }); + it('renders image', () => { + const mockImgSrc = 'image1.svg'; + + createComponent({ + propsData: { + panels: [{ name: 'test', href: '#', imageSrc: mockImgSrc }], + }, + }); + + expect(wrapper.find('img').attributes('src')).toBe(mockImgSrc); + }); + it('renders footer slot if provided', () => { const DUMMY = 'Test message'; createComponent({ diff --git a/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js b/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js index abc69da7a58..a7ddcbdd8bc 100644 --- a/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js +++ b/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js @@ -15,6 +15,7 @@ describe('Experimental new namespace creation app', () => { const findWelcomePage = () => wrapper.findComponent(WelcomePage); const findLegacyContainer = () => wrapper.findComponent(LegacyContainer); const findBreadcrumb = () => wrapper.findComponent(GlBreadcrumb); + const findImage = () => wrapper.find('img'); const findNewTopLevelGroupAlert = () => wrapper.findComponent(NewTopLevelGroupAlert); const findSuperSidebarToggle = () => wrapper.findComponent(SuperSidebarToggle); @@ -22,8 +23,8 @@ describe('Experimental new namespace creation app', () => { title: 'Create something', initialBreadcrumbs: [{ text: 'Something', href: '#' }], panels: [ - { name: 'panel1', selector: '#some-selector1' }, - { name: 'panel2', selector: '#some-selector2' }, + { name: 'panel1', selector: '#some-selector1', imageSrc: 'panel1.svg' }, + { name: 'panel2', selector: '#some-selector2', imageSrc: 'panel2.svg' }, ], persistenceKey: 'DEMO-PERSISTENCE-KEY', }; @@ -82,6 +83,10 @@ describe('Experimental new namespace creation app', () => { expect(breadcrumb.exists()).toBe(true); expect(breadcrumb.props().items[0].text).toBe(DEFAULT_PROPS.initialBreadcrumbs[0].text); }); + + it('renders images', () => { + expect(findImage().attributes('src')).toBe(DEFAULT_PROPS.panels[1].imageSrc); + }); }); it('renders extra description if provided', () => { diff --git a/spec/graphql/resolvers/users/participants_resolver_spec.rb b/spec/graphql/resolvers/users/participants_resolver_spec.rb index 63a14daabba..22111626c5b 100644 --- a/spec/graphql/resolvers/users/participants_resolver_spec.rb +++ b/spec/graphql/resolvers/users/participants_resolver_spec.rb @@ -137,7 +137,8 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do # 1 extra query per source (3 emojis + 2 notes) to fetch participables collection # 2 extra queries to load work item widgets collection - expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(7) + # 1 extra query to load the project creator to check if they are banned + expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(8) end it 'does not execute N+1 for system note metadata relation' do diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb index 64735f8b23b..b9316e46d9d 100644 --- a/spec/helpers/environment_helper_spec.rb +++ b/spec/helpers/environment_helper_spec.rb @@ -68,17 +68,5 @@ RSpec.describe EnvironmentHelper, feature_category: :environment_management do graphql_etag_key: environment.etag_cache_key }.to_json) end - - context 'when metrics dashboard feature is available' do - before do - stub_feature_flags(remove_monitor_metrics: false) - end - - it 'includes metrics path' do - expect(Gitlab::Json.parse(subject)).to include( - 'environment_metrics_path' => project_metrics_dashboard_path(project, environment: environment) - ) - end - end end end diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb index c0816f93a68..b69d6022e70 100644 --- a/spec/helpers/environments_helper_spec.rb +++ b/spec/helpers/environments_helper_spec.rb @@ -22,7 +22,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do expect(metrics_data).to include( 'settings_path' => edit_project_settings_integration_path(project, 'prometheus'), 'clusters_path' => project_clusters_path(project), - 'metrics_dashboard_base_path' => project_metrics_dashboard_path(project, environment: environment), 'current_environment_name' => environment.name, 'documentation_path' => help_page_path('administration/monitoring/prometheus/index.md'), 'add_dashboard_documentation_path' => help_page_path('operations/metrics/dashboards/index.md', anchor: 'add-a-new-dashboard-to-your-project'), @@ -30,7 +29,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do 'empty_loading_svg_path' => match_asset_path('/assets/illustrations/monitoring/loading.svg'), 'empty_no_data_svg_path' => match_asset_path('/assets/illustrations/monitoring/no_data.svg'), 'empty_unable_to_connect_svg_path' => match_asset_path('/assets/illustrations/monitoring/unable_to_connect.svg'), - 'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json), 'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json), 'default_branch' => 'master', 'project_path' => project_path(project), @@ -82,30 +80,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do it { is_expected.to include('environment_state' => 'stopped') } end - context 'when request is from project scoped metrics path' do - let(:request) { double('request', path: path) } - - before do - allow(helper).to receive(:request).and_return(request) - end - - context '/:namespace/:project/-/metrics' do - let(:path) { project_metrics_dashboard_path(project) } - - it 'uses correct path for metrics_dashboard_base_path' do - expect(metrics_data['metrics_dashboard_base_path']).to eq(project_metrics_dashboard_path(project)) - end - end - - context '/:namespace/:project/-/metrics/some_custom_dashboard.yml' do - let(:path) { "#{project_metrics_dashboard_path(project)}/some_custom_dashboard.yml" } - - it 'uses correct path for metrics_dashboard_base_path' do - expect(metrics_data['metrics_dashboard_base_path']).to eq(project_metrics_dashboard_path(project)) - end - end - end - context 'when metrics dashboard feature is unavailable' do before do stub_feature_flags(remove_monitor_metrics: true) diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index cde7fc0e272..07479d4e1e0 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -11,6 +11,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do let_it_be(:user) { create(:user) } before do + allow(helper).to receive(:current_user).and_return(user) helper.instance_variable_set(:@project, project) end @@ -143,7 +144,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do let(:project) { project_with_repo } before do - allow(helper).to receive(:current_user).and_return(user) allow(helper).to receive(:can?).with(user, :read_cross_project) { true } allow(user).to receive(:max_member_access_for_project).and_return(40) allow(Gitlab::I18n).to receive(:locale).and_return('es') @@ -287,10 +287,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end describe '#show_no_ssh_key_message?' do - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'user has no keys' do it 'returns true' do expect(helper.show_no_ssh_key_message?).to be_truthy @@ -307,10 +303,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end describe '#show_no_password_message?' do - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'user has password set' do it 'returns false' do expect(helper.show_no_password_message?).to be_falsey @@ -346,10 +338,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do describe '#no_password_message' do let(:user) { create(:user, password_automatically_set: true) } - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'password authentication is enabled for Git' do it 'returns message prompting user to set password or set up a PAT' do stub_application_setting(password_authentication_enabled_for_git?: true) @@ -431,10 +419,10 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end describe 'default_clone_protocol' do + let(:user) { nil } + context 'when user is not logged in and gitlab protocol is HTTP' do it 'returns HTTP' do - allow(helper).to receive(:current_user).and_return(nil) - expect(helper.send(:default_clone_protocol)).to eq('http') end end @@ -442,7 +430,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do context 'when user is not logged in and gitlab protocol is HTTPS' do it 'returns HTTPS' do stub_config_setting(protocol: 'https') - allow(helper).to receive(:current_user).and_return(nil) expect(helper.send(:default_clone_protocol)).to eq('https') end @@ -453,10 +440,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do let(:user) { double(:user, fork_of: nil) } let(:project) { double(:project, id: 1) } - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'when there is no current_user' do let(:user) { nil } @@ -543,10 +526,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do describe '#git_user_name' do let(:user) { build_stubbed(:user, name: 'John "A" Doe53') } - before do - allow(helper).to receive(:current_user).and_return(user) - end - it 'parses quotes in name' do expect(helper.send(:git_user_name)).to eq('John \"A\" Doe53') end @@ -554,9 +533,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do describe '#git_user_email' do context 'not logged-in' do - before do - allow(helper).to receive(:current_user).and_return(nil) - end + let(:user) { nil } it 'returns your@email.com' do expect(helper.send(:git_user_email)).to eq('your@email.com') @@ -564,10 +541,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end context 'user logged in' do - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'user has no configured commit email' do it 'returns the primary email' do expect(helper.send(:git_user_email)).to eq(user.email) @@ -807,9 +780,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do describe '#can_admin_project_member?' do context 'when user is project owner' do - before do - allow(helper).to receive(:current_user) { project.owner } - end + let(:user) { project.owner } it 'returns true for owner of project' do expect(helper.can_admin_project_member?(project)).to eq true @@ -829,7 +800,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do with_them do before do project.add_role(user, user_project_role) - allow(helper).to receive(:current_user) { user } end it 'resolves if the user can import members' do @@ -1016,7 +986,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do before do allow(helper).to receive(:can?) { true } - allow(helper).to receive(:current_user).and_return(user) end it 'includes project_permissions_settings' do @@ -1188,10 +1157,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end shared_examples 'configure import method modal' do - before do - allow(helper).to receive(:current_user).and_return(user) - end - context 'as a user' do it 'returns a link to contact an administrator' do allow(user).to receive(:can_admin_all_resources?).and_return(false) @@ -1290,16 +1255,14 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end describe '#can_admin_associated_clusters?' do - let_it_be(:current_user) { create(:user) } let_it_be_with_reload(:project) { create(:project) } subject { helper.send(:can_admin_associated_clusters?, project) } before do - allow(helper).to receive(:current_user).and_return(current_user) allow(helper) .to receive(:can?) - .with(current_user, :admin_cluster, namespace) + .with(user, :admin_cluster, namespace) .and_return(user_can_admin_cluster) end @@ -1477,8 +1440,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end it 'returns the data related to fork divergence' do - allow(helper).to receive(:current_user).and_return(user) - ahead_path = "/#{project.full_path}/-/compare/#{source_project.default_branch}...ref?from_project_id=#{source_project.id}" behind_path = @@ -1500,8 +1461,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do end it 'returns view_mr_path if a merge request for the branch exists' do - allow(helper).to receive(:current_user).and_return(user) - merge_request = create(:merge_request, source_project: project, target_project: project_with_repo, source_branch: project.default_branch, target_branch: project_with_repo.default_branch) @@ -1523,8 +1482,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do with_them do it 'create_mr_path is nil' do - allow(helper).to receive(:current_user).and_return(user) - project.add_member(user, project_role) source_project.add_member(user, source_project_role) @@ -1562,4 +1519,50 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do it { expect(subject).to eq('ssh_url_to_repo') } end + + describe '#can_view_branch_rules?' do + subject { helper.can_view_branch_rules? } + + context 'when user is a maintainer' do + before do + project.add_maintainer(user) + end + + it { is_expected.to be_truthy } + end + + context 'when user is a developer' do + before do + project.add_developer(user) + end + + it { is_expected.to be_falsey } + end + end + + describe '#can_push_code?' do + subject { helper.can_push_code? } + + context 'when user is nil' do + let(:user) { nil } + + it { is_expected.to be_falsey } + end + + context 'when user is a developer on the project' do + before do + project.add_developer(user) + end + + it { is_expected.to be_truthy } + end + + context 'when user is a reporter on the project' do + before do + project.add_reporter(user) + end + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb index 8ead292c27a..cf525801aa0 100644 --- a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb +++ b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb @@ -185,8 +185,6 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do subject { parsed_payload.metrics_dashboard_url } - it { is_expected.to eq(dashboard_url_for_alert) } - context 'without environment' do let(:raw_payload) { payload.except('labels') } diff --git a/spec/lib/gitlab/metrics/dashboard/url_spec.rb b/spec/lib/gitlab/metrics/dashboard/url_spec.rb index d49200f87cc..4045d957b44 100644 --- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb @@ -5,78 +5,6 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::Dashboard::Url do include Gitlab::Routing.url_helpers - describe '#metrics_regex' do - let(:environment_id) { 1 } - let(:url_params) do - [ - 'foo', - 'bar', - environment_id, - { - start: '2019-08-02T05:43:09.000Z', - dashboard: 'config/prometheus/common_metrics.yml', - group: 'awesome group', - anchor: 'title' - } - ] - end - - let(:expected_params) do - { - 'url' => url, - 'namespace' => 'foo', - 'project' => 'bar', - 'environment' => '1', - 'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z', - 'anchor' => '#title' - } - end - - subject { described_class.metrics_regex } - - context 'for /-/environments/:environment_id/metrics route' do - let(:url) { metrics_namespace_project_environment_url(*url_params) } - - it_behaves_like 'regex which matches url when expected' - end - - context 'for /-/metrics?environment=:environment_id route' do - let(:url) { namespace_project_metrics_dashboard_url(*url_params) } - let(:url_params) do - [ - 'namespace1', - 'project1', - { - environment: environment_id, - start: '2019-08-02T05:43:09.000Z', - dashboard: 'config/prometheus/common_metrics.yml', - group: 'awesome group', - anchor: 'title' - } - ] - end - - let(:expected_params) do - { - 'url' => url, - 'namespace' => 'namespace1', - 'project' => 'project1', - 'environment' => environment_id.to_s, - 'query' => "?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&environment=#{environment_id}&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z", - 'anchor' => '#title' - } - end - - it_behaves_like 'regex which matches url when expected' - end - - context 'for metrics_dashboard route' do - let(:url) { metrics_dashboard_namespace_project_environment_url(*url_params) } - - it_behaves_like 'regex which matches url when expected' - end - end - describe '#clusters_regex' do let(:url) { Gitlab::Routing.url_helpers.namespace_project_cluster_url(*url_params) } let(:url_params) do @@ -202,12 +130,4 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do end end end - - describe '#build_dashboard_url' do - it 'builds the url for the dashboard endpoint' do - url = described_class.build_dashboard_url('foo', 'bar', 1) - - expect(url).to match described_class.metrics_regex - end - end end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 9df869f8801..f7c81f93260 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -804,7 +804,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic let(:project) { create(:project) } let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" } let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" } - let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" } shared_examples "zero count" do it "does not count the issue" do @@ -824,7 +823,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic create(:issue, project: project, description: description_with_embed) # In-Valid create(:issue, project: project, description: description_with_unintegrated_embed) - create(:issue, project: project, description: description_with_non_grafana_inline_metric) create(:issue, project: project, description: nil) create(:issue, project: project, description: '') create(:issue, project: project) diff --git a/spec/mailers/emails/projects_spec.rb b/spec/mailers/emails/projects_spec.rb index ef3c21b32ce..1f0f09f7ca2 100644 --- a/spec/mailers/emails/projects_spec.rb +++ b/spec/mailers/emails/projects_spec.rb @@ -104,7 +104,6 @@ RSpec.describe Emails::Projects do let_it_be(:environment) { create(:environment, project: project) } let(:payload) { { 'gitlab_environment_name' => environment.name } } - let(:metrics_url) { metrics_project_environment_url(project, environment) } it_behaves_like 'an email sent from GitLab' it_behaves_like 'it should not have Gmail Actions links' @@ -131,7 +130,6 @@ RSpec.describe Emails::Projects do let(:alert) { create(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project) } let(:title) { "#{prometheus_alert.title} #{prometheus_alert.computed_operator} #{prometheus_alert.threshold}" } - let(:metrics_url) { metrics_project_environment_url(project, environment) } before do payload['labels'] = { @@ -157,7 +155,6 @@ RSpec.describe Emails::Projects do is_expected.to have_body_text(environment.name) is_expected.to have_body_text('Metric:') is_expected.to have_body_text(prometheus_alert.full_query) - is_expected.to have_body_text(metrics_url) is_expected.not_to have_body_text('Description:') end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 73489e6b35e..bb279132ac6 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -9059,6 +9059,67 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr end end + describe '.without_created_and_owned_by_banned_user' do + let_it_be(:other_project) { create(:project) } + + subject(:results) { described_class.without_created_and_owned_by_banned_user } + + context 'when project creator is not banned' do + let_it_be(:project_of_active_user) { create(:project, creator: create(:user)) } + + it 'includes the project' do + expect(results).to match_array([other_project, project_of_active_user]) + end + end + + context 'when project creator is banned' do + let_it_be(:banned_user) { create(:user, :banned) } + let_it_be(:project_of_banned_user) { create(:project, creator: banned_user) } + + context 'when project creator is also an owner' do + let_it_be(:project_auth) do + project = project_of_banned_user + create(:project_authorization, :owner, user: project.creator, project: project) + end + + it 'excludes the project' do + expect(results).to match_array([other_project]) + end + end + + context 'when project creator is not an owner' do + it 'includes the project' do + expect(results).to match_array([other_project, project_of_banned_user]) + end + end + end + end + + describe '#created_and_owned_by_banned_user?' do + subject { project.created_and_owned_by_banned_user? } + + context 'when creator is banned' do + let_it_be(:creator) { create(:user, :banned) } + let_it_be(:project) { create(:project, creator: creator) } + + it { is_expected.to eq false } + + context 'when creator is an owner' do + let_it_be(:project_auth) do + create(:project_authorization, :owner, user: project.creator, project: project) + end + + it { is_expected.to eq true } + end + end + + context 'when creator is not banned' do + let_it_be(:project) { create(:project) } + + it { is_expected.to eq false } + end + end + it_behaves_like 'something that has web-hooks' do let_it_be_with_reload(:object) { create(:project) } diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 94330dee912..42fe301ea9e 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -3217,6 +3217,32 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do end end + describe 'when project is created and owned by a banned user' do + let_it_be(:project) { create(:project, :public) } + + let(:current_user) { guest } + + before do + allow(project).to receive(:created_and_owned_by_banned_user?).and_return(true) + end + + it { expect_disallowed(:read_project) } + + context 'when current user is an admin', :enable_admin_mode do + let(:current_user) { admin } + + it { expect_allowed(:read_project) } + end + + context 'when hide_projects_of_banned_users FF is disabled' do + before do + stub_feature_flags(hide_projects_of_banned_users: false) + end + + it { expect_allowed(:read_project) } + end + end + private def project_subject(project_type) diff --git a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb index 3417f9529bd..2c49c9bc47b 100644 --- a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb +++ b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb @@ -40,12 +40,6 @@ RSpec.describe 'getting Alert Management Alert Assignees', feature_category: :in create(:alert_management_alert, :prometheus, project: project, payload: payload) end - it 'includes the correct metrics dashboard url' do - post_graphql(graphql_query, current_user: current_user) - - expect(first_alert).to include('metricsDashboardUrl' => dashboard_url_for_alert) - end - context 'when metrics dashboard feature is unavailable' do before do stub_feature_flags(remove_monitor_metrics: true) diff --git a/spec/rubocop/formatter/todo_formatter_spec.rb b/spec/rubocop/formatter/todo_formatter_spec.rb index fdd6117d0e6..55a64198289 100644 --- a/spec/rubocop/formatter/todo_formatter_spec.rb +++ b/spec/rubocop/formatter/todo_formatter_spec.rb @@ -106,6 +106,8 @@ RSpec.describe RuboCop::Formatter::TodoFormatter, feature_category: :tooling do Exclude: - 'd.rb' - 'app/views/project.html.haml.rb' + - 'app/views/project.haml.rb' + - 'app/views/project.text.haml.rb' - 'app/views/unrelated.html.haml.rb.ext' - 'app/views/unrelated.html.haml.ext' - 'app/views/unrelated.html.haml' @@ -122,7 +124,9 @@ RSpec.describe RuboCop::Formatter::TodoFormatter, feature_category: :tooling do B/TooManyOffenses: Exclude: - 'a.rb' + - 'app/views/project.haml.rb' - 'app/views/project.html.haml.rb' + - 'app/views/project.text.haml.rb' - 'c.rb' YAML end diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb index c60bead12c2..551acd2860d 100644 --- a/spec/serializers/environment_entity_spec.rb +++ b/spec/serializers/environment_entity_spec.rb @@ -83,32 +83,6 @@ RSpec.describe EnvironmentEntity do end end - context 'when metrics dashboard feature is available' do - before do - stub_feature_flags(remove_monitor_metrics: false) - end - - context 'metrics disabled' do - before do - allow(environment).to receive(:has_metrics?).and_return(false) - end - - it "doesn't expose metrics path" do - expect(subject).not_to include(:metrics_path) - end - end - - context 'metrics enabled' do - before do - allow(environment).to receive(:has_metrics?).and_return(true) - end - - it 'exposes metrics path' do - expect(subject).to include(:metrics_path) - end - end - end - it "doesn't expose metrics path" do expect(subject).not_to include(:metrics_path) end diff --git a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb index beed23a366f..53def716de3 100644 --- a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb +++ b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Metrics::Dashboard::ClusterDashboardService, :use_clean_rails_mem end describe '#get_dashboard' do - let(:service_params) { [project, user, { cluster: cluster, cluster_type: :project }] } + let(:service_params) { [project, user, { cluster: cluster, cluster_type: :admin }] } let(:service_call) { subject.get_dashboard } subject { described_class.new(*service_params) } diff --git a/spec/support/shared_contexts/prometheus/alert_shared_context.rb b/spec/support/shared_contexts/prometheus/alert_shared_context.rb index 932ab899270..13e739680c8 100644 --- a/spec/support/shared_contexts/prometheus/alert_shared_context.rb +++ b/spec/support/shared_contexts/prometheus/alert_shared_context.rb @@ -37,17 +37,6 @@ RSpec.shared_context 'self-managed prometheus alert attributes' do } } end - - let(:dashboard_url_for_alert) do - Gitlab::Routing.url_helpers.metrics_dashboard_project_environment_url( - project, - environment, - embed_json: embed_content, - embedded: true, - end: '2018-03-12T09:36:00Z', - start: '2018-03-12T08:36:00Z' - ) - end end RSpec.shared_context 'gitlab-managed prometheus alert attributes' do diff --git a/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb b/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb index 5b63ef10c85..013d722a8c1 100644 --- a/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb +++ b/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb @@ -12,33 +12,3 @@ RSpec.shared_examples_for 'GET #metrics_dashboard correctly formatted response' expect(found_keys).to contain_exactly(*expected_keys) end end - -RSpec.shared_examples_for 'GET #metrics_dashboard for dashboard' do |dashboard_name| - let(:expected_keys) { %w(dashboard status metrics_data) } - let(:status_code) { :ok } - - before do - stub_feature_flags(remove_monitor_metrics: false) - end - - it_behaves_like 'GET #metrics_dashboard correctly formatted response' - - it 'returns correct dashboard' do - get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json - - expect(json_response['dashboard']['dashboard']).to eq(dashboard_name) - end - - context 'when metrics dashboard feature is unavailable' do - before do - stub_feature_flags(remove_monitor_metrics: true) - end - - it 'returns 404 not found' do - get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json - - expect(response).to have_gitlab_http_status(:not_found) - expect(response.body).to be_empty - end - end -end diff --git a/spec/support/shared_examples/features/content_editor_shared_examples.rb b/spec/support/shared_examples/features/content_editor_shared_examples.rb index 2454bb7afc6..254bc3c83ac 100644 --- a/spec/support/shared_examples/features/content_editor_shared_examples.rb +++ b/spec/support/shared_examples/features/content_editor_shared_examples.rb @@ -572,7 +572,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi expect(find(suggestions_dropdown)).to have_text('My Cool Merge Request') - send_keys :enter + send_keys [:arrow_down, :enter] expect(page).not_to have_css(suggestions_dropdown) expect(page).to have_text('!1') @@ -583,7 +583,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi expect(find(suggestions_dropdown)).to have_text('My Cool Linked Issue') - send_keys :enter + send_keys [:arrow_down, :enter] expect(page).not_to have_css(suggestions_dropdown) expect(page).to have_text('#1') @@ -594,7 +594,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi expect(find(suggestions_dropdown)).to have_text('My Cool Milestone') - send_keys :enter + send_keys [:arrow_down, :enter] expect(page).not_to have_css(suggestions_dropdown) expect(page).to have_text('%My Cool Milestone') @@ -606,7 +606,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi expect(find(suggestions_dropdown)).to have_text('🙂 slight_smile') expect(find(suggestions_dropdown)).to have_text('😸 smile_cat') - send_keys :enter + send_keys [:arrow_down, :enter] expect(page).not_to have_css(suggestions_dropdown) @@ -636,7 +636,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi end def dropdown_scroll_top - evaluate_script("document.querySelector('#{suggestions_dropdown} .gl-dropdown-inner').scrollTop") + evaluate_script("document.querySelector('#{suggestions_dropdown}').scrollTop") end end end |