Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue16
-rw-r--r--app/assets/stylesheets/page_bundles/import.scss12
-rw-r--r--app/graphql/mutations/ci/job_token_scope/add_project.rb16
-rw-r--r--app/graphql/mutations/ci/project_ci_cd_settings_update.rb8
-rw-r--r--app/models/project.rb5
-rw-r--r--app/services/ci/job_token_scope/add_project_service.rb2
-rw-r--r--config/feature_flags/development/frozen_outbound_job_token_scopes.yml (renamed from config/feature_flags/development/ci_fix_max_includes.yml)12
-rw-r--r--config/feature_flags/development/frozen_outbound_job_token_scopes_override.yml8
-rw-r--r--config/feature_flags/development/record_issue_and_mr_assignee_events.yml2
-rw-r--r--config/feature_flags/development/use_primary_and_secondary_stores_for_rate_limiting.yml8
-rw-r--r--config/feature_flags/development/use_primary_store_as_default_for_rate_limiting.yml8
-rw-r--r--config/metrics/counts_28d/20230417064258_i_container_registry_writes_user_monthly.yml32
-rw-r--r--config/metrics/counts_7d/20230417063146_i_container_registry_writes_user_weekly.yml32
-rw-r--r--doc/administration/logs/index.md5
-rw-r--r--doc/administration/redis/troubleshooting.md2
-rw-r--r--doc/api/dora/metrics.md2
-rw-r--r--doc/api/graphql/reference/index.md6
-rw-r--r--doc/ci/interactive_web_terminal/index.md6
-rw-r--r--doc/development/features_inside_dot_gitlab.md1
-rw-r--r--doc/development/i18n/proofreader.md2
-rw-r--r--doc/user/profile/preferences.md15
-rw-r--r--doc/user/project/members/share_project_with_groups.md6
-rw-r--r--doc/user/project/remote_development/connect_machine.md4
-rw-r--r--doc/user/project/remote_development/index.md4
-rw-r--r--doc/user/project/repository/code_suggestions.md2
-rw-r--r--doc/user/project/web_ide/img/admin_live_preview_v13_0.pngbin5508 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/img/commit_changes_v13_11.pngbin116443 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/img/dark_theme_v13_0.pngbin99238 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/img/fuzzy_finder_v15_7.png (renamed from doc/user/project/web_ide_beta/img/fuzzy_finder_v15_7.png)bin121069 -> 121069 bytes
-rw-r--r--doc/user/project/web_ide/img/live_preview_v13_0.pngbin29188 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/img/solarized_dark_theme_v13_1.pngbin43014 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/img/terminal_status.pngbin3709 -> 0 bytes
-rw-r--r--doc/user/project/web_ide/index.md504
-rw-r--r--doc/user/project/web_ide_beta/index.md140
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/entities/project_job_token_scope.rb14
-rw-r--r--lib/api/project_job_token_scope.rb27
-rw-r--r--lib/gitlab/ci/config/external/mapper/verifier.rb32
-rw-r--r--lib/gitlab/redis.rb1
-rw-r--r--lib/gitlab/redis/cluster_rate_limiting.rb11
-rw-r--r--lib/gitlab/redis/rate_limiting.rb9
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/prometheus_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/grafana_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb4
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb6
-rw-r--r--spec/features/admin/admin_runners_spec.rb4
-rw-r--r--spec/features/explore/groups_spec.rb44
-rw-r--r--spec/features/groups/group_settings_spec.rb6
-rw-r--r--spec/features/groups/packages_spec.rb2
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb7
-rw-r--r--spec/features/projects/settings/forked_project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb2
-rw-r--r--spec/frontend/authentication/webauthn/authenticate_spec.js5
-rw-r--r--spec/frontend/authentication/webauthn/register_spec.js5
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js292
-rw-r--r--spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb52
-rw-r--r--spec/helpers/application_helper_spec.rb6
-rw-r--r--spec/helpers/labels_helper_spec.rb10
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb49
-rw-r--r--spec/lib/api/entities/project_job_token_scope_spec.rb38
-rw-r--r--spec/lib/container_registry/path_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/config/external/mapper/verifier_spec.rb50
-rw-r--r--spec/lib/gitlab/consul/internal_spec.rb6
-rw-r--r--spec/lib/gitlab/email/message/repository_push_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/project/export_task_spec.rb8
-rw-r--r--spec/lib/gitlab/redis/cluster_rate_limiting_spec.rb7
-rw-r--r--spec/mailers/emails/pages_domains_spec.rb10
-rw-r--r--spec/models/design_management/design_spec.rb12
-rw-r--r--spec/models/integrations/chat_message/deployment_message_spec.rb2
-rw-r--r--spec/models/issue_spec.rb12
-rw-r--r--spec/models/merge_request_spec.rb8
-rw-r--r--spec/models/milestone_spec.rb4
-rw-r--r--spec/models/operations/feature_flag_spec.rb6
-rw-r--r--spec/models/project_spec.rb6
-rw-r--r--spec/models/service_desk_setting_spec.rb4
-rw-r--r--spec/models/snippet_spec.rb8
-rw-r--r--spec/presenters/project_hook_presenter_spec.rb4
-rw-r--r--spec/presenters/service_hook_presenter_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb19
-rw-r--r--spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb51
-rw-r--r--spec/requests/api/internal/pages_spec.rb18
-rw-r--r--spec/requests/api/project_job_token_scope_spec.rb76
-rw-r--r--spec/requests/api/projects_spec.rb22
-rw-r--r--spec/requests/api/release/links_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb8
-rw-r--r--spec/services/ci/job_token_scope/add_project_service_spec.rb4
-rw-r--r--spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb2
-rw-r--r--spec/services/groups/transfer_service_spec.rb6
-rw-r--r--spec/services/projects/fork_service_spec.rb6
-rw-r--r--spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb2
-rw-r--r--spec/support/shared_examples/mailers/notify_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/user_activity_shared_examples.rb2
-rw-r--r--spec/uploaders/file_uploader_spec.rb8
94 files changed, 830 insertions, 1058 deletions
diff --git a/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue
index ee6b531c1ca..3db962c7fe8 100644
--- a/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue
+++ b/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue
@@ -80,9 +80,6 @@ export default {
'updateSelectedLabels',
'toggleDropdownContents',
]),
- isLabelSelected(label) {
- return this.selectedLabelsList.includes(label.id);
- },
/**
* This method scrolls item from dropdown into
* the view if it is off the viewable area of the
@@ -160,7 +157,11 @@ export default {
<template>
<gl-intersection-observer @appear="handleComponentAppear" @disappear="handleComponentDisappear">
- <div class="labels-select-contents-list js-labels-list" @keydown="handleKeyDown">
+ <div
+ class="labels-select-contents-list js-labels-list"
+ data-testid="labels-list"
+ @keydown="handleKeyDown"
+ >
<div
v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded"
class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!"
@@ -200,7 +201,11 @@ export default {
:highlight="index === currentHighlightItem"
@clickLabel="handleLabelClick(label)"
/>
- <li v-show="showNoMatchingResultsMessage" class="gl-p-3 gl-text-center">
+ <li
+ v-show="showNoMatchingResultsMessage"
+ class="gl-p-3 gl-text-center"
+ data-testid="no-matching-results"
+ >
{{ __('No matching results') }}
</li>
</ul>
@@ -210,6 +215,7 @@ export default {
<li v-if="allowLabelCreate">
<gl-link
class="gl-display-flex w-100 flex-row text-break-word label-item"
+ data-testid="create-label-link"
@click="handleCreateLabelClick"
>
{{ footerCreateLabelTitle }}
diff --git a/app/assets/stylesheets/page_bundles/import.scss b/app/assets/stylesheets/page_bundles/import.scss
index a6c08e344f9..0a856e217ef 100644
--- a/app/assets/stylesheets/page_bundles/import.scss
+++ b/app/assets/stylesheets/page_bundles/import.scss
@@ -4,19 +4,11 @@ $import-bar-height: $gl-spacing-scale-11;
.import-table-bar {
height: $import-bar-height;
- top: $header-height;
-
- html.with-performance-bar & {
- top: calc(#{$header-height} + #{$performance-bar-height});
- }
+ top: $calc-application-header-height;
}
.import-table {
thead {
- top: calc(#{$header-height} + #{$import-bar-height});
-
- html.with-performance-bar & {
- top: calc(#{$header-height} + #{$performance-bar-height} + #{$import-bar-height});
- }
+ top: calc(#{$calc-application-header-height} + #{$import-bar-height});
}
}
diff --git a/app/graphql/mutations/ci/job_token_scope/add_project.rb b/app/graphql/mutations/ci/job_token_scope/add_project.rb
index 6f0f87b47a1..6071d6750c2 100644
--- a/app/graphql/mutations/ci/job_token_scope/add_project.rb
+++ b/app/graphql/mutations/ci/job_token_scope/add_project.rb
@@ -21,16 +21,28 @@ module Mutations
argument :direction,
::Types::Ci::JobTokenScope::DirectionEnum,
required: false,
- description: 'Direction of access, which defaults to outbound.'
+ deprecated: {
+ reason: 'Outbound job token scope is being removed. This field can now only be set to INBOUND',
+ milestone: '16.0'
+ },
+ description: 'Direction of access, which defaults to INBOUND.'
field :ci_job_token_scope,
Types::Ci::JobTokenScopeType,
null: true,
description: "CI job token's access scope."
- def resolve(project_path:, target_project_path:, direction: :outbound)
+ def resolve(project_path:, target_project_path:, direction: nil)
project = authorized_find!(project_path)
target_project = Project.find_by_full_path(target_project_path)
+ frozen_outbound = project.frozen_outbound_job_token_scopes?
+
+ if direction == :outbound && frozen_outbound
+ raise Gitlab::Graphql::Errors::ArgumentError, 'direction: OUTBOUND scope entries can only be removed. ' \
+ 'Only INBOUND scope can be expanded.'
+ end
+
+ direction ||= frozen_outbound ? :inbound : :outbound
result = ::Ci::JobTokenScope::AddProjectService
.new(project, current_user)
diff --git a/app/graphql/mutations/ci/project_ci_cd_settings_update.rb b/app/graphql/mutations/ci/project_ci_cd_settings_update.rb
index fcba729d460..90658f05827 100644
--- a/app/graphql/mutations/ci/project_ci_cd_settings_update.rb
+++ b/app/graphql/mutations/ci/project_ci_cd_settings_update.rb
@@ -19,6 +19,10 @@ module Mutations
argument :job_token_scope_enabled, GraphQL::Types::Boolean,
required: false,
+ deprecated: {
+ reason: 'Outbound job token scope is being removed. This field can now only be set to false',
+ milestone: '16.0'
+ },
description: 'Indicates CI/CD job tokens generated in this project ' \
'have restricted access to other projects.'
@@ -39,6 +43,10 @@ module Mutations
def resolve(full_path:, **args)
project = authorized_find!(full_path)
+ if args[:job_token_scope_enabled] && project.frozen_outbound_job_token_scopes?
+ raise Gitlab::Graphql::Errors::ArgumentError, 'job_token_scope_enabled can only be set to false'
+ end
+
settings = project.ci_cd_settings
settings.update(args)
diff --git a/app/models/project.rb b/app/models/project.rb
index 146747eb57a..7aa13a94c8f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -3168,6 +3168,11 @@ class Project < ApplicationRecord
group.crm_enabled?
end
+ def frozen_outbound_job_token_scopes?
+ Feature.enabled?(:frozen_outbound_job_token_scopes, self) && Feature.disabled?(:frozen_outbound_job_token_scopes_override, self)
+ end
+ strong_memoize_attr :frozen_outbound_job_token_scopes?
+
private
def pages_unique_domain_enabled?
diff --git a/app/services/ci/job_token_scope/add_project_service.rb b/app/services/ci/job_token_scope/add_project_service.rb
index 4f745042f07..704aa28f8c5 100644
--- a/app/services/ci/job_token_scope/add_project_service.rb
+++ b/app/services/ci/job_token_scope/add_project_service.rb
@@ -5,7 +5,7 @@ module Ci
class AddProjectService < ::BaseService
include EditScopeValidations
- def execute(target_project, direction: :outbound)
+ def execute(target_project, direction: :inbound)
validate_edit!(project, target_project, current_user)
link = allowlist(direction)
diff --git a/config/feature_flags/development/ci_fix_max_includes.yml b/config/feature_flags/development/frozen_outbound_job_token_scopes.yml
index b70fb3f1222..a73e3b4d4eb 100644
--- a/config/feature_flags/development/ci_fix_max_includes.yml
+++ b/config/feature_flags/development/frozen_outbound_job_token_scopes.yml
@@ -1,8 +1,8 @@
---
-name: ci_fix_max_includes
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112963
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390909
-milestone: '15.10'
+name: frozen_outbound_job_token_scopes
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118254
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/407401
+milestone: '16.0'
type: development
-group: group::pipeline authoring
-default_enabled: true
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/frozen_outbound_job_token_scopes_override.yml b/config/feature_flags/development/frozen_outbound_job_token_scopes_override.yml
new file mode 100644
index 00000000000..44dcb134318
--- /dev/null
+++ b/config/feature_flags/development/frozen_outbound_job_token_scopes_override.yml
@@ -0,0 +1,8 @@
+---
+name: frozen_outbound_job_token_scopes_override
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118254
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/407401
+milestone: '16.0'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/record_issue_and_mr_assignee_events.yml b/config/feature_flags/development/record_issue_and_mr_assignee_events.yml
index 4d63f1bf4d4..83660a2a4a6 100644
--- a/config/feature_flags/development/record_issue_and_mr_assignee_events.yml
+++ b/config/feature_flags/development/record_issue_and_mr_assignee_events.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/397050
milestone: '15.11'
type: development
group: group::optimize
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/use_primary_and_secondary_stores_for_rate_limiting.yml b/config/feature_flags/development/use_primary_and_secondary_stores_for_rate_limiting.yml
deleted file mode 100644
index f6679a52ff2..00000000000
--- a/config/feature_flags/development/use_primary_and_secondary_stores_for_rate_limiting.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_primary_and_secondary_stores_for_rate_limiting
-introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106123"
-rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/385681"
-milestone: '15.9'
-type: development
-group: group::scalability
-default_enabled: false
diff --git a/config/feature_flags/development/use_primary_store_as_default_for_rate_limiting.yml b/config/feature_flags/development/use_primary_store_as_default_for_rate_limiting.yml
deleted file mode 100644
index a958c1c3247..00000000000
--- a/config/feature_flags/development/use_primary_store_as_default_for_rate_limiting.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_primary_store_as_default_for_rate_limiting
-introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106123"
-rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/385681"
-milestone: '15.9'
-type: development
-group: group::scalability
-default_enabled: false
diff --git a/config/metrics/counts_28d/20230417064258_i_container_registry_writes_user_monthly.yml b/config/metrics/counts_28d/20230417064258_i_container_registry_writes_user_monthly.yml
new file mode 100644
index 00000000000..a114ce9fbaa
--- /dev/null
+++ b/config/metrics/counts_28d/20230417064258_i_container_registry_writes_user_monthly.yml
@@ -0,0 +1,32 @@
+---
+key_path: redis_hll_counters.user_container_registry.i_container_registry_writes_user_monthly
+description: A monthly count of unique users that have executed write operations to the registry
+product_section: ops
+product_stage: package
+product_group: package
+value_type: number
+status: active
+milestone: "16.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117779
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: AggregatedMetric
+options:
+ aggregate:
+ operator: OR
+ attribute: user_id
+ events:
+ - i_container_registry_push_tag_user
+ - i_container_registry_delete_tag_user
+ - i_container_registry_delete_repository_user
+ - i_container_registry_create_repository_user
+ - i_container_registry_push_repository_user
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20230417063146_i_container_registry_writes_user_weekly.yml b/config/metrics/counts_7d/20230417063146_i_container_registry_writes_user_weekly.yml
new file mode 100644
index 00000000000..5d521a7840a
--- /dev/null
+++ b/config/metrics/counts_7d/20230417063146_i_container_registry_writes_user_weekly.yml
@@ -0,0 +1,32 @@
+---
+key_path: redis_hll_counters.user_container_registry.i_container_registry_writes_user_weekly
+description: A weekly count of unique users that have executed write operations to the registry
+product_section: ops
+product_stage: package
+product_group: package
+value_type: number
+status: active
+milestone: "16.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117779
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: AggregatedMetric
+options:
+ aggregate:
+ operator: OR
+ attribute: user_id
+ events:
+ - i_container_registry_push_tag_user
+ - i_container_registry_delete_tag_user
+ - i_container_registry_delete_repository_user
+ - i_container_registry_create_repository_user
+ - i_container_registry_push_repository_user
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/doc/administration/logs/index.md b/doc/administration/logs/index.md
index 55d760111d1..c85abda221e 100644
--- a/doc/administration/logs/index.md
+++ b/doc/administration/logs/index.md
@@ -96,6 +96,7 @@ except those captured by `runit`.
| [LogRotate logs](#logrotate-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Mailroom](#mail_room_jsonlog-default) | **{check-circle}** Yes | **{check-circle}** Yes |
| [NGINX](#nginx-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| [PgBouncer logs](#pgbouncer-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
| [PostgreSQL logs](#postgresql-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Praefect logs](#praefect-logs) | **{dotted-circle}** Yes | **{check-circle}** Yes |
| [Prometheus logs](#prometheus-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
@@ -1093,6 +1094,10 @@ For Omnibus GitLab installations, Mattermost logs are in these locations:
For Omnibus GitLab installations, Workhorse logs are in `/var/log/gitlab/gitlab-workhorse/current`.
+## PgBouncer logs
+
+For Omnibus GitLab installations, PgBouncer logs are in `/var/log/gitlab/pgbouncer/current`.
+
## PostgreSQL logs
For Omnibus GitLab installations, PostgreSQL logs are in `/var/log/gitlab/postgresql/current`.
diff --git a/doc/administration/redis/troubleshooting.md b/doc/administration/redis/troubleshooting.md
index fbfe52570c4..947db2c1d4e 100644
--- a/doc/administration/redis/troubleshooting.md
+++ b/doc/administration/redis/troubleshooting.md
@@ -123,7 +123,7 @@ To make sure your configuration is correct:
```
WARNING:
- This action affects services, and takes the instance down for up to 20 seconds. If successful,
+ This action affects services, and takes the instance down for up to 20 seconds. If successful,
it should recover after that.
1. Then back in the Rails console from the first step, run:
diff --git a/doc/api/dora/metrics.md b/doc/api/dora/metrics.md
index a1515413bed..9d81a82f520 100644
--- a/doc/api/dora/metrics.md
+++ b/doc/api/dora/metrics.md
@@ -11,7 +11,7 @@ type: reference, api
> - The legacy key/value pair `{ "<date>" => "<value>" }` was removed from the payload in GitLab 14.0.
> `time_to_restore_service` metric was introduced in GitLab 14.9.
-You can also retrieve [DORA metrics](../../user/analytics/dora_metrics.md) with the [GraphQL API](../../api/graphql/reference/index.md).
+You can also retrieve [DORA metrics](../../user/analytics/dora_metrics.md) with the [GraphQL API](../../api/graphql/reference/index.md).
All methods require at least the Reporter role.
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 004e3075437..cb184b1e7a8 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1424,7 +1424,7 @@ Input type: `CiCdSettingsUpdateInput`
| <a id="mutationcicdsettingsupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcicdsettingsupdatefullpath"></a>`fullPath` | [`ID!`](#id) | Full Path of the project the settings belong to. |
| <a id="mutationcicdsettingsupdateinboundjobtokenscopeenabled"></a>`inboundJobTokenScopeEnabled` | [`Boolean`](#boolean) | Indicates CI/CD job tokens generated in other projects have restricted access to this project. |
-| <a id="mutationcicdsettingsupdatejobtokenscopeenabled"></a>`jobTokenScopeEnabled` | [`Boolean`](#boolean) | Indicates CI/CD job tokens generated in this project have restricted access to other projects. |
+| <a id="mutationcicdsettingsupdatejobtokenscopeenabled"></a>`jobTokenScopeEnabled` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Outbound job token scope is being removed. This field can now only be set to false. Deprecated in 16.0. |
| <a id="mutationcicdsettingsupdatekeeplatestartifact"></a>`keepLatestArtifact` | [`Boolean`](#boolean) | Indicates if the latest artifact should be kept for the project. |
| <a id="mutationcicdsettingsupdatemergepipelinesenabled"></a>`mergePipelinesEnabled` | [`Boolean`](#boolean) | Indicates if merge pipelines are enabled for the project. |
| <a id="mutationcicdsettingsupdatemergetrainsenabled"></a>`mergeTrainsEnabled` | [`Boolean`](#boolean) | Indicates if merge trains are enabled for the project. |
@@ -1447,7 +1447,7 @@ Input type: `CiJobTokenScopeAddProjectInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcijobtokenscopeaddprojectclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationcijobtokenscopeaddprojectdirection"></a>`direction` | [`CiJobTokenScopeDirection`](#cijobtokenscopedirection) | Direction of access, which defaults to outbound. |
+| <a id="mutationcijobtokenscopeaddprojectdirection"></a>`direction` **{warning-solid}** | [`CiJobTokenScopeDirection`](#cijobtokenscopedirection) | **Deprecated:** Outbound job token scope is being removed. This field can now only be set to INBOUND. Deprecated in 16.0. |
| <a id="mutationcijobtokenscopeaddprojectprojectpath"></a>`projectPath` | [`ID!`](#id) | Project that the CI job token scope belongs to. |
| <a id="mutationcijobtokenscopeaddprojecttargetprojectpath"></a>`targetProjectPath` | [`ID!`](#id) | Project to be added to the CI job token scope. |
@@ -4869,7 +4869,7 @@ Input type: `ProjectCiCdSettingsUpdateInput`
| <a id="mutationprojectcicdsettingsupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationprojectcicdsettingsupdatefullpath"></a>`fullPath` | [`ID!`](#id) | Full Path of the project the settings belong to. |
| <a id="mutationprojectcicdsettingsupdateinboundjobtokenscopeenabled"></a>`inboundJobTokenScopeEnabled` | [`Boolean`](#boolean) | Indicates CI/CD job tokens generated in other projects have restricted access to this project. |
-| <a id="mutationprojectcicdsettingsupdatejobtokenscopeenabled"></a>`jobTokenScopeEnabled` | [`Boolean`](#boolean) | Indicates CI/CD job tokens generated in this project have restricted access to other projects. |
+| <a id="mutationprojectcicdsettingsupdatejobtokenscopeenabled"></a>`jobTokenScopeEnabled` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Outbound job token scope is being removed. This field can now only be set to false. Deprecated in 16.0. |
| <a id="mutationprojectcicdsettingsupdatekeeplatestartifact"></a>`keepLatestArtifact` | [`Boolean`](#boolean) | Indicates if the latest artifact should be kept for the project. |
| <a id="mutationprojectcicdsettingsupdatemergepipelinesenabled"></a>`mergePipelinesEnabled` | [`Boolean`](#boolean) | Indicates if merge pipelines are enabled for the project. |
| <a id="mutationprojectcicdsettingsupdatemergetrainsenabled"></a>`mergeTrainsEnabled` | [`Boolean`](#boolean) | Indicates if merge trains are enabled for the project. |
diff --git a/doc/ci/interactive_web_terminal/index.md b/doc/ci/interactive_web_terminal/index.md
index c7fb94535ff..a7923cb84a0 100644
--- a/doc/ci/interactive_web_terminal/index.md
+++ b/doc/ci/interactive_web_terminal/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Interactive Web Terminals **(FREE)**
+# Interactive web terminals **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/50144) in GitLab 11.3.
@@ -77,6 +77,6 @@ close the terminal window.
![finished job with terminal open](img/finished_job_with_terminal_open.png)
-## Interactive Web Terminals for the Web IDE
+## Interactive web terminals for the Web IDE
-Read the Web IDE docs to learn how to run [Interactive Terminals through the Web IDE](../../user/project/web_ide/index.md#interactive-web-terminals-for-the-web-ide).
+To run interactive web terminals for the Web IDE, see [Web IDE](../../user/project/web_ide/index.md).
diff --git a/doc/development/features_inside_dot_gitlab.md b/doc/development/features_inside_dot_gitlab.md
index f1915327c8c..f35b37db84e 100644
--- a/doc/development/features_inside_dot_gitlab.md
+++ b/doc/development/features_inside_dot_gitlab.md
@@ -18,4 +18,3 @@ When implementing new features, please refer to these existing features to avoid
- [Customize Auto DevOps Helm Values](../topics/autodevops/customize.md#customize-helm-chart-values): `.gitlab/auto-deploy-values.yaml`.
- [Insights](../user/project/insights/index.md#configure-project-insights): `.gitlab/insights.yml`.
- [Service Desk Templates](../user/project/service_desk.md#create-customized-email-templates): `.gitlab/service_desk_templates/`.
-- [Web IDE](../user/project/web_ide/index.md#web-ide-configuration-file): `.gitlab/.gitlab-webide.yml`.
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index 964bee8620e..480aa54f180 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -19,7 +19,7 @@ are very appreciative of the work done by translators and proofreaders!
- Tsegaselassie Tadesse - [GitLab](https://gitlab.com/tsega), [Crowdin](https://crowdin.com/profile/tsegaselassi)
- Arabic
- Proofreaders needed.
-- Belarusian
+- Belarusian
- Anton Katsuba - [GitLab](https://gitlab.com/coinvariant), [Crowdin](https://crowdin.com/profile/aerialfiddle)
- Bosnian
- Haris Delalić - [GitLab](https://gitlab.com/haris.delalic), [Crowdin](https://crowdin.com/profile/haris.delalic)
diff --git a/doc/user/profile/preferences.md b/doc/user/profile/preferences.md
index 696a5f4b42e..0428a66cd37 100644
--- a/doc/user/profile/preferences.md
+++ b/doc/user/profile/preferences.md
@@ -185,21 +185,6 @@ NOTE:
This feature is experimental, and choosing absolute times might break certain layouts.
Open an issue if you notice that using absolute times breaks a layout.
-## Web IDE
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/370139) in GitLab 15.7 [with a flag](../../administration/feature_flags.md) named `vscode_web_ide`. Disabled by default.
-> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/371084) in GitLab 15.7.
-> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741) in GitLab 15.11.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named `vscode_web_ide`. On GitLab.com, this feature is available.
-
-The [Web IDE Beta](../project/web_ide_beta/index.md) is
-the default editing environment. To stop using the Web IDE Beta:
-
-1. In the **Web IDE** section, select the **Opt out of the Web IDE Beta** checkbox.
-1. Select **Save changes**.
-
## Integrations
Configure your preferences with third-party services which provide enhancements to your GitLab experience.
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index 02a563f59b5..452363c3d9a 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -28,6 +28,8 @@ To invite a group to a project, you must be at least one of the following:
In addition:
+- You must be a member of the group or the subgroup being invited.
+
- The [visibility level](../../public_access.md#project-and-group-visibility) of the group you're inviting
must be at least as restrictive as that of the project. For example, you can invite:
- A _private_ group to a _private_ project
@@ -37,10 +39,10 @@ must be at least as restrictive as that of the project. For example, you can inv
- An _internal_ group to a _public_ project.
- A _public_ group to a _public_ project.
-- The group or subgroup must be in the project's [namespace](../../namespace/index.md).
+- If the project's root ancestor group [does not allow the project to be shared outside the hierarchy](../../group/access_and_permissions.md#prevent-group-sharing-outside-the-group-hierarchy), the invited group or subgroup must be in the project's [namespace](../../namespace/index.md).
For example, a project in the namespace `group/subgroup01/project`:
- Can be shared with `group/subgroup02` or `group/subgroup01/subgroup03`.
- - Cannot be shared with `group`.
+ - Cannot be shared with `group_abc`.
## Share a project with a group
diff --git a/doc/user/project/remote_development/connect_machine.md b/doc/user/project/remote_development/connect_machine.md
index f8fdd626852..f981918c0ea 100644
--- a/doc/user/project/remote_development/connect_machine.md
+++ b/doc/user/project/remote_development/connect_machine.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
This tutorial shows you how to:
- Create a development environment outside of GitLab.
-- Connect a remote machine to the [Web IDE](../web_ide_beta/index.md).
+- Connect a remote machine to the [Web IDE](../web_ide/index.md).
To connect a remote machine to the Web IDE, you must:
@@ -49,6 +49,8 @@ To generate Let's Encrypt certificates:
--preferred-challenges dns certonly
```
+Now that you've generated the certificates, it's time to create and connect a development environment.
+
## Connect a development environment to the Web IDE
To connect a development environment to the Web IDE:
diff --git a/doc/user/project/remote_development/index.md b/doc/user/project/remote_development/index.md
index e3c2b6ccfb2..fc03bab80b6 100644
--- a/doc/user/project/remote_development/index.md
+++ b/doc/user/project/remote_development/index.md
@@ -26,7 +26,7 @@ sole discretion of GitLab Inc.
## Web IDE as a frontend
-You can use the [Web IDE](../web_ide_beta/index.md) to make, commit, and push changes to a project directly from your web browser.
+You can use the [Web IDE](../web_ide/index.md) to make, commit, and push changes to a project directly from your web browser.
This way, you can update any project without having to install any dependencies or clone any repositories locally.
The Web IDE, however, lacks a native runtime environment where you could compile code, run tests, or generate real-time feedback.
@@ -48,7 +48,7 @@ A workspace is a virtual sandbox environment for your code that includes:
You can create a workspace from scratch or from a template that you can also customize.
-When you configure and connect a workspace to the [Web IDE](../web_ide_beta/index.md), you can:
+When you configure and connect a workspace to the [Web IDE](../web_ide/index.md), you can:
- Edit files directly from the Web IDE and commit and push changes to GitLab.
- Use the Web IDE to run tests, debug code, and view real-time feedback.
diff --git a/doc/user/project/repository/code_suggestions.md b/doc/user/project/repository/code_suggestions.md
index f7a772c6b68..6d3ce5267cf 100644
--- a/doc/user/project/repository/code_suggestions.md
+++ b/doc/user/project/repository/code_suggestions.md
@@ -22,7 +22,7 @@ as you type. Depending on the cursor position, the extension either:
To accept a suggestion, press <kbd>Tab</kbd>.
-Code Suggestions are supported in Visual Studio Code with the GitLab Workflow extension. GitLab plans to support the [new GitLab WebIDE in an upcoming release](../web_ide_beta/index.md) in the future.
+Code Suggestions are supported in Visual Studio Code with the GitLab Workflow extension.
Code Suggestions may produce [low-quality or incomplete suggestions](#model-accuracy-and-quality). Beta users should read about the [known limitations](#known-limitations). The best results from Code Suggestions are expected for these six languages:
diff --git a/doc/user/project/web_ide/img/admin_live_preview_v13_0.png b/doc/user/project/web_ide/img/admin_live_preview_v13_0.png
deleted file mode 100644
index 90129d240bc..00000000000
--- a/doc/user/project/web_ide/img/admin_live_preview_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/img/commit_changes_v13_11.png b/doc/user/project/web_ide/img/commit_changes_v13_11.png
deleted file mode 100644
index 6cd270a6112..00000000000
--- a/doc/user/project/web_ide/img/commit_changes_v13_11.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/img/dark_theme_v13_0.png b/doc/user/project/web_ide/img/dark_theme_v13_0.png
deleted file mode 100644
index 020578a9444..00000000000
--- a/doc/user/project/web_ide/img/dark_theme_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide_beta/img/fuzzy_finder_v15_7.png b/doc/user/project/web_ide/img/fuzzy_finder_v15_7.png
index 66ebae15e98..66ebae15e98 100644
--- a/doc/user/project/web_ide_beta/img/fuzzy_finder_v15_7.png
+++ b/doc/user/project/web_ide/img/fuzzy_finder_v15_7.png
Binary files differ
diff --git a/doc/user/project/web_ide/img/live_preview_v13_0.png b/doc/user/project/web_ide/img/live_preview_v13_0.png
deleted file mode 100644
index f701e137a6b..00000000000
--- a/doc/user/project/web_ide/img/live_preview_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/img/solarized_dark_theme_v13_1.png b/doc/user/project/web_ide/img/solarized_dark_theme_v13_1.png
deleted file mode 100644
index 8eca352a4d0..00000000000
--- a/doc/user/project/web_ide/img/solarized_dark_theme_v13_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/img/terminal_status.png b/doc/user/project/web_ide/img/terminal_status.png
deleted file mode 100644
index 91c341a9854..00000000000
--- a/doc/user/project/web_ide/img/terminal_status.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index 889ab1442b6..e40790cf9f3 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -6,465 +6,183 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Web IDE **(FREE)**
-The Web IDE is an advanced editor with commit staging.
-You can use the Web IDE to make changes to multiple files directly from the
-GitLab UI. For a more basic implementation, see [Web Editor](../repository/web_editor.md).
-
-NOTE:
-The Web IDE is being updated to use VS Code. For details,
-see [Web IDE Beta](../web_ide_beta/index.md).
-
-## Open the Web IDE
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95169) in GitLab 15.7 [with a flag](../../../administration/feature_flags.md) named `vscode_web_ide`. Disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/371084) in GitLab 15.7.
+> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741) in GitLab 15.11.
-Use the <kbd>.</kbd> [keyboard shortcut](../../shortcuts.md) to open the Web IDE.
-You can also open the Web IDE when viewing a file, from the repository file list,
-and from merge requests:
-
-### When viewing a file or the repository file list
-
- 1. In the upper-right corner of the page, select **Open in Web IDE** if it is visible.
- 1. If **Open in Web IDE** is not visible:
- 1. Select the (**{chevron-lg-down}**) next to **Edit** or **Gitpod**, depending on your configuration.
- 1. Select **Open in Web IDE** from the list to display it as the editing option.
- 1. Select **Open in Web IDE** to open the editor.
+The Web IDE is an advanced editor with commit staging.
+You can use the Web IDE to make changes to multiple files directly from the GitLab UI.
+For a more basic implementation, see [Web Editor](../repository/web_editor.md).
-### When viewing a merge request
+To pair the Web IDE with a remote development environment, see [remote development](../remote_development/index.md).
- 1. Go to your merge request.
- 1. In the upper-right corner, select **Code > Open in Web IDE**.
+## Use the Web IDE
-## File finder
+To open the Web IDE from the GitLab UI:
-The file finder allows you to quickly open files in the current branch by
-searching for fragments of the file path. The file finder is launched using the keyboard shortcut
-<kbd>Command</kbd>+<kbd>p</kbd>, <kbd>Control</kbd>+<kbd>p</kbd>, or <kbd>t</kbd>
-(when editor is not in focus). Type the filename or file path fragments to
-start seeing results.
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. Use the <kbd>.</kbd> keyboard shortcut.
-## Command palette
+You can also open the Web IDE from:
-You can see all available commands for manipulating editor content by pressing
-the <kbd>F1</kbd> key when the editor is in focus. After that, the editor displays
-a complete list of available commands for
-manipulating editor content. The editor supports commands for multi-cursor
-editing, code block folding, commenting, searching and replacing, navigating
-editor warnings and suggestions, and more.
+- A file
+- The repository file list
+- A merge request
-Some commands have a keyboard shortcut assigned to them. The command palette
-displays this shortcut next to each command. You can use this shortcut to invoke
-the command without having to select it in the command palette.
+### From a file or the repository file list
-For a full list of keyboard shortcuts in the Web IDE, refer to the
-[Keyboard shortcuts](../../shortcuts.md#web-ide) list.
+To open the Web IDE from a file or the repository file list:
-## Syntax highlighting
+- In the upper-right corner of the page, select **Open in Web IDE**.
-As expected from an IDE, syntax highlighting for many languages in
-the Web IDE makes your direct editing even easier.
+If **Open in Web IDE** is not visible:
-The Web IDE currently provides:
+1. Next to **Edit** or **Gitpod**, select the down arrow (**{chevron-lg-down}**).
+1. From the dropdown list, select **Open in Web IDE**.
+1. Select **Open in Web IDE**.
-- Basic syntax colorization for a variety of programming, scripting and markup
- languages such as XML, PHP, C#, C++, Markdown, Java, VB, Batch, Python, Ruby,
- and Objective-C.
-- IntelliSense and validation support (displaying errors and warnings, providing
- smart completions, formatting, and outlining) for some languages. For example:
- TypeScript, JavaScript, CSS, LESS, SCSS, JSON, and HTML.
+### From a merge request
-Because the Web IDE is based on the [Monaco Editor](https://microsoft.github.io/monaco-editor/),
-you can find a more complete list of supported languages in the
-[Monaco languages](https://github.com/Microsoft/monaco-languages) repository. Under the hood,
-Monaco uses the [Monarch](https://microsoft.github.io/monaco-editor/monarch.html) library for syntax highlighting.
+To open the Web IDE from a merge request:
-If you are missing Syntax Highlighting support for any language, we prepared a short guide on how to [add support for a missing language Syntax Highlighting.](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/ide/lib/languages/README.md)
+1. Go to your merge request.
+1. In the upper-right corner, select **Code > Open in Web IDE**.
-### Themes
+The Web IDE opens new and modified files in separate tabs and displays changes side by side with the original source.
+To optimize loading time, only the top 10 files (by number of lines changed) are opened automatically.
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2389) in GitLab 13.0.
-> - Full Solarized Dark Theme [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219228) in GitLab 13.1.
-> - Full [Solarized Light](https://gitlab.com/gitlab-org/gitlab/-/issues/221035) and [Monokai](https://gitlab.com/gitlab-org/gitlab/-/issues/221034) Themes introduced in GitLab 13.6.
+In the file tree, any new or modified file in the merge request is indicated by an icon next to the filename.
+To view changes to a file, right-click the filename and select **Compare with merge request base**.
-All the themes GitLab supports for syntax highlighting are applied to the entire Web IDE screen.
-You can pick a theme from your [profile preferences](../../profile/preferences.md).
+## Open a file in the Web IDE
-| Solarized Dark Theme | Dark Theme |
-|-------------------------------------------------------------|-----------------------------------------|
-| ![Solarized Dark Theme](img/solarized_dark_theme_v13_1.png) | ![Dark Theme](img/dark_theme_v13_0.png) |
+To open any file by its name:
-## Link to specific lines
+1. Press <kbd>Command</kbd>+<kbd>P</kbd>.
+1. Enter the name of your file.
-The Web IDE and the [Web Editor](../repository/web_editor.md) share the
-same core features. To link to specific lines in the Web IDE, see
-[Web Editor](../repository/web_editor.md#link-to-specific-lines).
+![fuzzy_finder_v15_7](img/fuzzy_finder_v15_7.png)
-## Schema based validation
+## Search across files
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218472) validation based on predefined schemas in GitLab 13.2 [with a flag](../../../administration/feature_flags.md) named `schema_linting`.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104399) in GitLab 15.7.
-> - On self-managed GitLab [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107488) in GitLab 15.8.
+You can use the Web IDE to search all files in the opened folder.
-The Web IDE provides validation support for certain JSON and YAML files using schemas
-based on the [JSON Schema Store](https://www.schemastore.org/json/).
+To search across files:
-### Predefined schemas
+1. Press <kbd>Shift</kbd>+<kbd>Command</kbd>+<kbd>F</kbd>.
+1. Enter your search term.
-The Web IDE has validation for certain files built in. This feature is only supported for
-the `*.gitlab-ci.yml` files.
+In the Web IDE, only partial results from opened files are displayed.
-### Custom schemas **(PREMIUM)**
+## View a list of changed files
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/226982) in GitLab 13.4.
+To view a list of files you changed in the Web IDE:
-The Web IDE also allows you to define custom schemas for certain JSON/YAML files in your project.
-You can do so by defining a `schemas` entry in the `.gitlab/.gitlab-webide.yml` file inside the
-repository's root. Here is an example configuration:
+- On the activity bar on the left, select **Source Control**,
+ or press <kbd>Control</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd>.
-```yaml
-schemas:
- - uri: https://json.schemastore.org/package
- match:
- - package.json
- - uri: https://somewebsite.com/first/raw/url
- match:
- - data/release_posts/unreleased/*.{yml,yaml}
- - uri: https://somewebsite.com/second/raw/url
- match:
- - "*.meta.json"
-```
+Your `CHANGES`, `STAGED CHANGES`, and `MERGE CHANGES` are displayed.
+For more information, see the [VS Code documentation](https://code.visualstudio.com/docs/sourcecontrol/overview#_commit).
-Each schema entry supports two properties:
+## Switch branches
-- `uri`: Provide an absolute URL for the schema definition file here.
- The schema from this URL is loaded when a matching file is open.
-- `match`: A list of matching paths or glob expressions. If a schema matches a
- particular path pattern, it is applied to that file. Enclose the pattern
- in quotes if it begins with an asterisk (`*`), it's be applied to that file.
- If a pattern begins with an asterisk (`*`), enclose it in quotation marks.
- Otherwise, the configuration file is not valid YAML.
+The Web IDE uses the currently selected branch by default.
+To switch branches in the Web IDE:
-## Configure the Web IDE
+1. On the status bar, in the lower-left corner, select the current branch name.
+1. In the search box, start typing the branch name.
+1. From the dropdown list, select the branch.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23352) in GitLab 13.1.
+## Create a branch
-The Web IDE supports configuration of certain editor settings by using
-[`.editorconfig` files](https://editorconfig.org/). When opening a file, the
-Web IDE looks for a file named `.editorconfig` in the current directory
-and all parent directories. If a configuration file is found and has settings
-that match the file's path, these settings are enforced on the opened file.
+To create a branch from the current branch in the Web IDE:
-The Web IDE currently supports the following `.editorconfig` settings:
+1. On the status bar, in the lower-left corner, select the current branch name.
+1. From the dropdown list, select **Create new branch...**.
+1. Enter the branch name.
+1. Press <kbd>Enter</kbd>.
-- `indent_style`
-- `indent_size`
-- `end_of_line`
-- `trim_trailing_whitespace`
-- `tab_width`
-- `insert_final_newline`
+If you don't have write access to the repository, **Create new branch...** is not visible.
## Commit changes
-> - [Starting](https://gitlab.com/gitlab-org/gitlab/-/issues/33441) with GitLab 12.7, files are automatically staged.
-> - In GitLab 12.9, support for staging files was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/196609) to prevent loss of unstaged data. All of your current changes must be committed or discarded.
-
-After making your changes, select **Commit** on the bottom-left to
-review the list of changed files.
-
-After you have finalized your changes, you can add a commit message, commit the
-changes and directly create a merge request. In case you don't have write
-access to the selected branch, you see a warning, but can still create
-a new branch and start a merge request.
-
-To discard a change in a particular file, select **Discard changes** on that
-file in the changes tab. To discard all the changes, select the trash icon in the
-upper-right corner of the changes sidebar.
-
-![Commit changes](img/commit_changes_v13_11.png)
-
-## Reviewing changes
-
-Before you commit your changes, you can compare them with the previous commit
-by switching to the review mode or selecting the file from the list of changes.
-
-An additional review mode is available when you open a merge request, which
-shows you a preview of the merge request diff if you commit your changes.
-
-## View CI job logs
-
-You can use the Web IDE to quickly fix failing tests by opening
-the branch or merge request in the Web IDE and opening the logs of the failed
-job. You can access the status of all jobs for the most recent pipeline and job
-traces for the current commit by selecting the **Pipelines** button in the top
-right.
-
-The pipeline status is also shown at all times in the status bar in the bottom
-left.
-
-## Switching merge requests
-
-To switch between your authored and assigned merge requests, select the
-dropdown list in the top of the sidebar to open a list of merge requests. You must commit or discard all your changes before switching to a different merge
-request.
-
-## Switching branches
-
-To switch between branches of the current project repository, select the dropdown list
-in the top of the sidebar to open a list of branches.
-You must commit or discard all your changes before switching to a
-different branch.
-
-## Markdown editing
-
-> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in GitLab 13.1.
-> - Side-by-side Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68274) in GitLab 14.3.
-
-To edit Markdown files in the Web IDE:
+To commit changes in the Web IDE:
-1. Go to your repository, and navigate to the Markdown page you want to edit.
-1. Select **Open in Web IDE**, and GitLab loads the page in a tab in the editor.
-1. Make your changes to the file. GitLab supports [GitLab Flavored Markdown (GLFM)](../../markdown.md).
-1. When your changes are complete, select **Commit** in the left sidebar.
-1. Add a commit message, select the branch you want to commit to, and select **Commit**.
+1. On the activity bar on the left, select **Source Control**,
+ or press <kbd>Control</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd>.
+1. Enter your commit message.
+1. Select **Commit & Push**.
+1. Commit to the current branch, or create a new branch.
-When editing, you can upload local images by pasting them directly in the Markdown file.
-The image is uploaded to the same directory and is named `image.png` by default.
-If another file already exists with the same name, a numeric suffix is automatically
-added to the filename.
+## Use the command palette
-There are two ways to preview Markdown content in the Web IDE:
+In the Web IDE, you can access many commands through the command palette.
+To open the command palette and run a command in the Web IDE:
-1. At the top of the file's tab, select **Preview Markdown** to preview the formatting
- in your file. You can't edit the file in this view.
- 1. To add more changes to the file, select **Edit**.
-1. Right-click or use the keyboard shortcut `Command/Control + Shift + P` and
- select **Preview Markdown** to toggle a live Markdown preview panel.
+1. Press <kbd>Shift</kbd>+<kbd>Command</kbd>+<kbd>P</kbd>.
+1. In the search box, start typing the command name.
+1. From the dropdown list, select the command.
-<!--- start_remove The following content will be removed on remove_date: '2023-02-01' -->
+## Edit settings
-## Live Preview (removed)
+You can use the settings editor to view and modify your user and workspace settings.
+To open the settings editor in the Web IDE:
-WARNING:
-This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108627) in GitLab 15.8
-and is planned for removal in 15.9. This change is a breaking change.
+- On the top menu bar, select **File > Preferences > Settings**,
+ or press <kbd>Command</kbd>+<kbd>,</kbd>.
-> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/213853) from _Client Side Evaluation_ to _Live Preview_ in GitLab 13.0.
+In the settings editor, you can search for the settings you want to modify.
-You can use the Web IDE to preview JavaScript projects right in the browser.
-This feature uses CodeSandbox to compile and bundle the JavaScript used to
-preview the web application.
+## Edit keyboard shortcuts
-![Web IDE Live Preview](img/live_preview_v13_0.png)
+You can use the keyboard shortcuts editor to view and modify the default keybindings for all available commands.
+To open the keyboard shortcuts editor in the Web IDE:
-Additionally, for public projects an **Open in CodeSandbox** button is available
-to transfer the contents of the project into a public CodeSandbox project to
-quickly share your project with others.
+- On the top menu bar, select **File > Preferences > Keyboard Shortcuts**,
+ or press <kbd>Command</kbd>+<kbd>K</kbd> then <kbd>Command</kbd>+<kbd>S</kbd>.
-### Enable Live Preview
+In the keyboard shortcuts editor, you can search for:
-With Live Preview enabled, you can preview projects with a `package.json` file and
-a `main` entry point inside the Web IDE.
+- The keybindings you want to change
+- The commands you want to add or remove keybindings for
-Live Preview is enabled for all projects on GitLab.com. If you are an administrator
-of a self-managed GitLab instance, and you want to enable Live Preview:
+Keybindings are based on your keyboard layout. If you change your keyboard layout, existing keybindings are updated automatically.
-1. On the top bar, select **Main menu > Admin**.
-1. On the left sidebar, select **Settings > General**.
-1. Scroll to **Web IDE** and select **Expand**:
- ![Administrator Live Preview setting](img/admin_live_preview_v13_0.png)
-1. Select **Enable Live Preview** and select **Save changes**.
+## Change themes
-[In GitLab 12.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/268288),
-third-party assets and libraries required for Live Preview are hosted at
-`https://sandbox-prod.gitlab-static.net` when it is enabled. However, some libraries
-are still served from other third-party services, which may or may not be desirable
-in your environment.
+You can choose between different themes for the Web IDE. The default theme for the Web IDE is **GitLab Dark**.
-An example `package.json`:
+To change the Web IDE theme:
-```json
-{
- "main": "index.js",
- "dependencies": {
- "vue": "latest"
- }
-}
-```
+1. On the top menu bar, select **File > Preferences > Theme > Color Theme**,
+ or press <kbd>Command</kbd>+<kbd>K</kbd> then <kbd>Command</kbd>+<kbd>T</kbd>.
+1. From the dropdown list, preview the themes with the arrow keys.
+1. Select a theme.
-<!--- end_remove -->
+The active color theme is stored in the [user settings](#edit-settings).
-## Interactive Web Terminals for the Web IDE
+## Privacy and data collection for extensions
-> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) from GitLab Ultimate to GitLab Free in 13.1.
+The Web IDE Extension Marketplace is based on Open VSX. Open VSX does not collect any
+data about you or your activities on the platform.
-WARNING:
-Interactive Web Terminals for the Web IDE is currently in [Beta](../../../policy/alpha-beta-support.md#beta).
-GitLab.com shared runners [do not yet support Interactive Web Terminals](https://gitlab.com/gitlab-org/gitlab/-/issues/24674),
-so you must use your own private runner to make use of this feature.
+However, the privacy and data collection practices of extensions available on Open VSX can vary.
+Some extensions might collect data to provide personalized recommendations or to improve the functionality.
+Other extensions might collect data for analytics or advertising purposes.
-[Interactive Web Terminals](../../../ci/interactive_web_terminal/index.md)
-give the project [Maintainers](../../permissions.md#project-members-permissions)
-user access to a terminal to interact with the runner directly from
-GitLab, including through the Web IDE.
+To protect your privacy and data:
-### Runner configuration
+- Carefully review the permissions requested by an extension before you install the extension.
+- Keep your extensions up to date to ensure that any security or privacy vulnerabilities are addressed promptly.
-Some things must be configured in the runner for the interactive web terminal
-to work:
+## Interactive web terminals for the Web IDE (Beta)
-- The runner needs to have
- [`[session_server]` configured properly](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-session_server-section).
- This section requires at least a `session_timeout` value (which defaults to 1800
- seconds) and a `listen_address` value. If `advertise_address` is not defined, `listen_address` is used.
-- If you are using a reverse proxy with your GitLab instance, web terminals must be
- [enabled](../../../administration/integration/terminal.md#enabling-and-disabling-terminal-support).
+When you set up a remote development server in the Web IDE, you can use interactive web terminals to:
-If you have the terminal open and the job has finished with its tasks, the
-terminal blocks the job from finishing for the duration configured in
-[`[session_server].session_timeout`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-session_server-section)
-until you close the terminal window.
-
-NOTE:
-Not all executors are
-[supported](https://docs.gitlab.com/runner/executors/#compatibility-chart).
-The [File Sync](#file-syncing-to-web-terminal) feature is supported on Kubernetes runners only.
-
-### Web IDE configuration file
-
-To enable the Web IDE terminals you must create the file
-`.gitlab/.gitlab-webide.yml` inside the repository's root. This
-file is fairly similar to the [`.gitlab-ci.yml` file](../../../ci/yaml/index.md)
-syntax but with some restrictions:
-
-- No global blocks (such as `before_script` or `after_script`) can be defined.
-- Only one job named `terminal` can be added to this file.
-- Only the keywords `image`, `services`, `tags`, `before_script`, `script`, and
- `variables` are allowed to be used to configure the job.
-- To connect to the interactive terminal, the `terminal` job must be still alive
- and running, otherwise the terminal cannot connect to the job's session.
- By default the `script` keyword has the value `sleep 60` to prevent
- the job from ending and giving the Web IDE enough time to connect. This means
- that, if you override the default `script` value, you have to add a command
- which would keep the job running, like `sleep`.
-
-For example, with this configuration file:
-
-```yaml
-terminal:
- # This can be any image that has the necessary runtime environment for your project.
- image: node:10-alpine
- before_script:
- - apk update
- script: sleep 60
- variables:
- RAILS_ENV: "test"
- NODE_ENV: "test"
-```
-
-After the terminal starts, the console is displayed and you can access
-the project repository files.
-
-When you use the `image` keyword, a container with the specified image is created.
-If you use the [shell executor](https://docs.gitlab.com/runner/executors/shell.html)
-or the [SSH executor](https://docs.gitlab.com/runner/executors/ssh.html), `image` has no effect.
-
-The terminal job is branch dependent. The configuration file used to trigger
-and configure the terminal is the one in the selected branch of the Web IDE.
-If no configuration file exists in a branch, an error message is displayed.
-
-### Running interactive terminals in the Web IDE
-
-If Interactive Terminals are available for the current user, the **Terminal** button is visible in the right sidebar of the Web IDE. Select this button to open
-or close the terminal tab.
-
-After opening, the tab shows the **Start Web Terminal** button. This button may
-be disabled if the environment is not configured correctly. If so, a status
-message describes the issue. Here are some reasons why **Start Web Terminal**
-may be disabled:
-
-- `.gitlab/.gitlab-webide.yml` does not exist or is set up incorrectly.
-- No active private runners are available for the project.
-
-If active, selecting the **Start Web Terminal** button loads the terminal view
-and start connecting to the runner's terminal. At any time, the **Terminal** tab
-can be closed and reopened and the state of the terminal is not affected.
-
-When the terminal is started and is successfully connected to the runner, then the
-runner's shell prompt appears in the terminal. From here, you can enter
-commands executed in the runner's environment. This is similar
-to running commands in a local terminal or through SSH.
-
-While the terminal is running, it can be stopped by selecting **Stop Terminal**.
-This disconnects the terminal and stops the runner's terminal job. From here,
-select **Restart Terminal** to start a new terminal session.
-
-### File syncing to web terminal
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5276) in GitLab 12.0.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211686) from GitLab Ultimate to GitLab Free in 13.1.
-
-File changes in the Web IDE can be synced to a running web terminal.
-This enables users to test their code changes in a preconfigured terminal
-environment.
-
-NOTE:
-Only file changes in the Web IDE are synced to the terminal.
-Changes made in the terminal are **not** synced to the Web IDE.
-This feature is only available for Kubernetes runners.
-
-To enable file syncing to the web terminal, the `.gitlab/.gitlab-webide.yml`
-file needs to have a `webide-file-sync` service configured. Here is an example
-configuration for a Node JS project which uses this service:
-
-```yaml
-terminal:
- # This can be any image that has the necessary runtime environment for your project.
- image:
- name: node:10-alpine
- services:
- - name: registry.gitlab.com/gitlab-org/webide-file-sync:latest
- alias: webide-file-sync
- entrypoint: ["/bin/sh"]
- command: ["-c", "sleep 5 && ./webide-file-sync -project-dir $CI_PROJECT_DIR"]
- ports:
- # The `webide-file-sync` executable defaults to port 3000.
- - number: 3000
-```
-
-- The `webide-file-sync` executable must start **after** the project
- directory is available. This is why we must add `sleep 5` to the `command`.
- See [this issue](https://gitlab.com/gitlab-org/webide-file-sync/-/issues/7) for
- more information.
-- `$CI_PROJECT_DIR` is a
- [predefined CI/CD variable](../../../ci/variables/predefined_variables.md)
- for GitLab Runners. This is where your project's repository resides.
-
-After you have configured the web terminal for file syncing, then when the web
-terminal is started, a **Terminal** status is visible in the status bar.
-
-![Web IDE Client Side Evaluation](img/terminal_status.png)
-
-Changes made to your files via the Web IDE sync to the running terminal
-when:
-
-- <kbd>Control</kbd> + <kbd>S</kbd> (or <kbd>Command</kbd> + <kbd>S</kbd> on Mac)
- is pressed while editing a file.
-- You select any area outside the file editor after editing a file.
-- A file or folder is created, deleted, or renamed.
-
-## Known issues
-
-The Web IDE has a few limitations:
-
-- Interactive Terminals is in a beta phase and continues to be improved in upcoming releases. In the meantime, the user is limited to having only one
- active terminal at a time.
-- LFS files can be rendered and displayed but they cannot be updated and committed using the Web IDE. If an LFS file is modified and pushed to the repository, the LFS pointer in the repository is overwritten with the modified LFS file content.
+- Access a remote shell on the server.
+- Interact with the server's file system and execute commands remotely.
-## Troubleshooting
-
-### Web terminals
+You cannot use interactive web terminals to interact with a runner.
+However, you can use a terminal to install dependencies and compile and debug code.
-- If the terminal's text is gray and unresponsive, then the terminal has stopped
- and it can no longer be used. A stopped terminal can be restarted by selecting
- **Restart Terminal**.
-- If the terminal displays **Connection Failure**, then the terminal could not
- connect to the runner. Try to stop and restart the terminal. If the
- problem persists, double check your runner configuration.
+For more information about configuring a workspace that supports interactive web terminals, see [remote development](../remote_development/index.md).
diff --git a/doc/user/project/web_ide_beta/index.md b/doc/user/project/web_ide_beta/index.md
index 933634f0c29..a4c733be376 100644
--- a/doc/user/project/web_ide_beta/index.md
+++ b/doc/user/project/web_ide_beta/index.md
@@ -1,137 +1,11 @@
---
-stage: Create
-group: IDE
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+redirect_to: '../web_ide/index.md'
+remove_date: '2023-08-22'
---
-# Web IDE Beta **(FREE)**
+This document was moved to [another location](../web_ide/index.md).
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95169) in GitLab 15.7 [with a flag](../../../administration/feature_flags.md) named `vscode_web_ide`. Disabled by default.
-> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/371084) in GitLab 15.7.
-> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741) in GitLab 15.11.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `vscode_web_ide`. On GitLab.com, this feature is available.
-
-As announced in [this blog post](https://about.gitlab.com/blog/2022/05/23/the-future-of-the-gitlab-web-ide/),
-the current implementation of the [Web IDE](../web_ide/index.md) is being replaced
-with an implementation powered by Visual Studio Code. This effort is still under
-development. For updates, see [this epic](https://gitlab.com/groups/gitlab-org/-/epics/7683).
-
-To pair the Web IDE Beta with a Remote Development environment, see [Remote Development](../remote_development/index.md).
-
-## Use the Web IDE Beta
-
-To open the Web IDE Beta from anywhere in the UI:
-
-- Use the <kbd>.</kbd> [keyboard shortcut](../../shortcuts.md).
-
-You can also open the Web IDE Beta when viewing a file, the repository file list,
-or a merge request.
-
-### Use when viewing a file or the repository file list
-
-To open the Web IDE Beta from a file or the repository file list:
-
-- In the upper-right corner of the page, select **Open in Web IDE**.
-
-If **Open in Web IDE** is not visible:
-
-1. Next to **Edit** or **Gitpod**, select the down arrow (**{chevron-lg-down}**).
-1. From the list, select **Open in Web IDE**.
-1. Select **Open in Web IDE**.
-
-### Use when viewing a merge request
-
-To open the Web IDE Beta from a merge request:
-
-1. Go to your merge request.
-1. In the upper-right corner, select **Code > Open in Web IDE**.
-
-The Web IDE Beta opens new and modified files in separate tabs and displays changes side by side with the original source. To optimize loading time, only the top 10 files (by number of lines changed) are opened automatically.
-
-In the file tree, any new or modified file in the merge request is indicated by an icon next to the filename. To view changes to a file, right-click the filename and select **Compare with merge request base**.
-
-## Open a file in the Web IDE Beta
-
-To open any file by its name:
-
-1. Press <kbd>Command</kbd>+<kbd>P</kbd>.
-1. Enter the name of your file.
-
-![fuzzy_finder_v15_7](img/fuzzy_finder_v15_7.png)
-
-## Switch branches
-
-The Web IDE Beta uses the currently selected branch by default.
-To switch branches in the Web IDE Beta:
-
-1. On the status bar, in the lower-left corner, select the current branch name.
-1. In the search box, start typing the branch name.
-1. From the dropdown list, select the branch.
-
-## Create a branch
-
-To create a branch from the current branch in the Web IDE Beta:
-
-1. On the status bar, in the lower-left corner, select the current branch name.
-1. From the dropdown list, select **Create new branch...**.
-1. Enter the branch name.
-1. Press <kbd>Enter</kbd>.
-
-If you don't have write access to the repository, **Create new branch...** is not visible.
-
-## Search across files
-
-You can use VS Code to quickly search all files in the opened folder.
-
-To search across files:
-
-1. Press <kbd>Shift</kbd>+<kbd>Command</kbd>+<kbd>F</kbd>.
-1. Enter your search term.
-
-In the Web IDE Beta, only partial results from opened files are displayed.
-Full file search is planned for a later date.
-
-## View a list of changed files
-
-To view a list of files you changed in the Web IDE Beta,
-on the Activity Bar on the left, select **Source Control**.
-Your `CHANGES`, `STAGED CHANGES`, and `MERGE CHANGES` are displayed.
-
-For details, see the [VS Code documentation](https://code.visualstudio.com/docs/sourcecontrol/overview#_commit).
-
-## Commit changes
-
-To commit your changes in the Web IDE Beta:
-
-1. On the Activity Bar on the left, select **Source Control**,
-or press <kbd>Control</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd>.
-1. Enter your commit message.
-1. Select **Commit & Push**.
-1. Commit to the current branch, or create a new branch.
-
-## Open the command palette
-
-In the Web IDE Beta, you can access many commands through the command palette.
-To open the command palette and run a command in the Web IDE Beta:
-
-1. Press <kbd>F1</kbd> or <kbd>Shift</kbd>+<kbd>Command</kbd>+<kbd>P</kbd>.
-1. In the search box, start typing the command name.
-1. From the dropdown list, select the command.
-
-## Stop using the Web IDE Beta
-
-If you do not want to use the Web IDE Beta, you can change your personal preferences.
-
-1. On the top bar, in the upper-right corner, select your avatar.
-1. Select **Preferences**.
-1. In the **Web IDE** section, select the **Opt out of the Web IDE Beta** checkbox.
-1. Select **Save changes**.
-
-## Known issues
-
-The [Web Terminal](../web_ide/index.md#interactive-web-terminals-for-the-web-ide)
-and [Live Preview](../web_ide/index.md#live-preview-removed) are not available in the Web IDE Beta.
-
-These features might become available at a later date.
+<!-- This redirect file can be deleted after <2023-08-22>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 674b91faeef..be11e022af3 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -266,6 +266,7 @@ module API
mount ::API::ProjectExport
mount ::API::ProjectHooks
mount ::API::ProjectImport
+ mount ::API::ProjectJobTokenScope
mount ::API::ProjectPackages
mount ::API::ProjectRepositoryStorageMoves
mount ::API::ProjectSnippets
diff --git a/lib/api/entities/project_job_token_scope.rb b/lib/api/entities/project_job_token_scope.rb
new file mode 100644
index 00000000000..0954db3a2fc
--- /dev/null
+++ b/lib/api/entities/project_job_token_scope.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ class ProjectJobTokenScope < Grape::Entity
+ expose(:inbound_enabled, documentation: { type: 'boolean' }) do |project, _|
+ project.ci_inbound_job_token_scope_enabled?
+ end
+ expose(:outbound_enabled, documentation: { type: 'boolean' }) do |project, _|
+ project.ci_outbound_job_token_scope_enabled?
+ end
+ end
+ end
+end
diff --git a/lib/api/project_job_token_scope.rb b/lib/api/project_job_token_scope.rb
new file mode 100644
index 00000000000..7fd288491ef
--- /dev/null
+++ b/lib/api/project_job_token_scope.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module API
+ class ProjectJobTokenScope < ::API::Base
+ before { authenticate! }
+
+ feature_category :secrets_management
+ urgency :low
+
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ desc 'Fetch CI_JOB_TOKEN access settings.' do
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not found' }
+ ]
+ success code: 200, model: Entities::ProjectJobTokenScope
+ tags %w[projects_job_token_scope]
+ end
+ get ':id/job_token_scope' do
+ authorize_admin_project
+
+ present user_project, with: Entities::ProjectJobTokenScope
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/external/mapper/verifier.rb b/lib/gitlab/ci/config/external/mapper/verifier.rb
index 7284d2a7e01..3472f2c581a 100644
--- a/lib/gitlab/ci/config/external/mapper/verifier.rb
+++ b/lib/gitlab/ci/config/external/mapper/verifier.rb
@@ -16,12 +16,10 @@ module Gitlab
end
files.each do |file|
- if YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
- # When running a pipeline, some Ci::ProjectConfig sources prepend the config content with an
- # "internal" `include`. We use this condition to exclude that `include` from the included file set.
- context.expandset << file unless context.internal_include?
- verify_max_includes!
- end
+ # When running a pipeline, some Ci::ProjectConfig sources prepend the config content with an
+ # "internal" `include`. We use this condition to exclude that `include` from the included file set.
+ context.expandset << file unless context.internal_include?
+ verify_max_includes!
verify_execution_time!
@@ -39,25 +37,20 @@ module Gitlab
# We do not combine the loops because we need to load the content of all files via `BatchLoader`.
files.each do |file| # rubocop:disable Style/CombinableLoops
- verify_max_includes! unless YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
verify_execution_time!
file.validate_content! if file.valid?
file.load_and_validate_expanded_hash! if file.valid?
-
- context.expandset << file unless YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
end
end
# rubocop: enable Metrics/CyclomaticComplexity
def legacy_process_without_instrumentation(files)
files.each do |file|
- if YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
- # When running a pipeline, some Ci::ProjectConfig sources prepend the config content with an
- # "internal" `include`. We use this condition to exclude that `include` from the included file set.
- context.expandset << file unless context.internal_include?
- verify_max_includes!
- end
+ # When running a pipeline, some Ci::ProjectConfig sources prepend the config content with an
+ # "internal" `include`. We use this condition to exclude that `include` from the included file set.
+ context.expandset << file unless context.internal_include?
+ verify_max_includes!
verify_execution_time!
@@ -69,22 +62,15 @@ module Gitlab
# We do not combine the loops because we need to load the content of all files before continuing
# to call `BatchLoader` for all locations.
files.each do |file| # rubocop:disable Style/CombinableLoops
- verify_max_includes! unless YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
verify_execution_time!
file.validate_content! if file.valid?
file.load_and_validate_expanded_hash! if file.valid?
-
- context.expandset << file unless YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
end
end
def verify_max_includes!
- if YamlProcessor::FeatureFlags.enabled?(:ci_fix_max_includes)
- return if context.expandset.count <= context.max_includes
- else
- return if context.expandset.count < context.max_includes # rubocop:disable Style/IfInsideElse
- end
+ return if context.expandset.count <= context.max_includes
raise Mapper::TooManyIncludesError, "Maximum of #{context.max_includes} nested includes are allowed!"
end
diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb
index 4d15022cca5..4bc1d6c3989 100644
--- a/lib/gitlab/redis.rb
+++ b/lib/gitlab/redis.rb
@@ -13,7 +13,6 @@ module Gitlab
Gitlab::Redis::Queues,
Gitlab::Redis::RateLimiting,
Gitlab::Redis::RepositoryCache,
- Gitlab::Redis::ClusterRateLimiting,
Gitlab::Redis::Sessions,
Gitlab::Redis::SharedState,
Gitlab::Redis::TraceChunks
diff --git a/lib/gitlab/redis/cluster_rate_limiting.rb b/lib/gitlab/redis/cluster_rate_limiting.rb
deleted file mode 100644
index e9d1e4f0c3f..00000000000
--- a/lib/gitlab/redis/cluster_rate_limiting.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Redis
- class ClusterRateLimiting < ::Gitlab::Redis::Wrapper
- def self.config_fallback
- Cache
- end
- end
- end
-end
diff --git a/lib/gitlab/redis/rate_limiting.rb b/lib/gitlab/redis/rate_limiting.rb
index 62ab00c2408..74b4ca12d18 100644
--- a/lib/gitlab/redis/rate_limiting.rb
+++ b/lib/gitlab/redis/rate_limiting.rb
@@ -15,15 +15,6 @@ module Gitlab
def cache_store
@cache_store ||= RateLimitingStore.new(redis: pool, namespace: Cache::CACHE_NAMESPACE)
end
-
- private
-
- def redis
- primary_store = ::Redis.new(::Gitlab::Redis::ClusterRateLimiting.params)
- secondary_store = ::Redis.new(params)
-
- MultiStore.new(primary_store, secondary_store, name.demodulize)
- end
end
end
end
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 8caed2d3ac6..8bddf51a434 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -123,7 +123,7 @@ RSpec.describe Projects::ClustersController, feature_category: :deployment_manag
{
id: proxyable.id.to_s,
namespace_id: project.namespace.full_path,
- project_id: project.name
+ project_id: project.path
}
end
diff --git a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
index 6b0c164e432..ef2d743c82f 100644
--- a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
+++ b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Projects::Environments::PrometheusApiController do
{
id: proxyable.id.to_s,
namespace_id: project.namespace.full_path,
- project_id: project.name
+ project_id: project.path
}
end
diff --git a/spec/controllers/projects/grafana_api_controller_spec.rb b/spec/controllers/projects/grafana_api_controller_spec.rb
index c953ea02a15..7c74511e5b4 100644
--- a/spec/controllers/projects/grafana_api_controller_spec.rb
+++ b/spec/controllers/projects/grafana_api_controller_spec.rb
@@ -180,7 +180,7 @@ RSpec.describe Projects::GrafanaApiController, feature_category: :metrics do
embedded: true,
grafana_url: 'https://grafana.example.com',
namespace_id: project.namespace.full_path,
- project_id: project.name
+ project_id: project.path
}
end
diff --git a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
index ca95d95a730..dc59dda3322 100644
--- a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
+++ b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Projects::PerformanceMonitoring::DashboardsController do
post :create, params: params
expect(response).to have_gitlab_http_status :created
- expect(controller).to set_flash[:notice].to eq("Your dashboard has been copied. You can <a href=\"/-/ide/project/#{namespace.path}/#{project.name}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}\">edit it here</a>.")
+ expect(controller).to set_flash[:notice].to eq("Your dashboard has been copied. You can <a href=\"/-/ide/project/#{project.full_path}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}\">edit it here</a>.")
expect(json_response).to eq('status' => 'success', 'dashboard' => { 'path' => ".gitlab/dashboards/#{file_name}" })
end
@@ -203,7 +203,7 @@ RSpec.describe Projects::PerformanceMonitoring::DashboardsController do
put :update, params: params
expect(response).to have_gitlab_http_status :created
- expect(controller).to set_flash[:notice].to eq("Your dashboard has been updated. You can <a href=\"/-/ide/project/#{namespace.path}/#{project.name}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}\">edit it here</a>.")
+ expect(controller).to set_flash[:notice].to eq("Your dashboard has been updated. You can <a href=\"/-/ide/project/#{project.full_path}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}\">edit it here</a>.")
expect(json_response).to eq('status' => 'success', 'dashboard' => { 'default' => false, 'display_name' => "custom_dashboard.yml", 'path' => ".gitlab/dashboards/#{file_name}", 'system_dashboard' => false })
end
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 2afd080344d..17bf9308834 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -158,9 +158,9 @@ RSpec.describe Projects::ReleasesController do
it_behaves_like 'successful request'
- it 'is accesible at a URL encoded path' do
+ it 'is accessible at a URL encoded path' do
expect(edit_project_release_path(project, release))
- .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%2Fv1.0/edit")
+ .to eq("/#{project.full_path}/-/releases/awesome%2Fv1.0/edit")
end
end
@@ -199,7 +199,7 @@ RSpec.describe Projects::ReleasesController do
it 'is accesible at a URL encoded path' do
expect(project_release_path(project, release))
- .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%2Fv1.0")
+ .to eq("/#{project.full_path}/-/releases/awesome%2Fv1.0")
end
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 5703ab1eaff..d82f9acdd07 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -634,7 +634,7 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do
assigned_project = page.find('[data-testid="assigned-projects"]')
expect(page).to have_content('Runner assigned to project.')
- expect(assigned_project).to have_content(project2.path)
+ expect(assigned_project).to have_content(project2.name)
end
end
@@ -674,7 +674,7 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do
new_runner_project = page.find('[data-testid="unassigned-projects"]')
expect(page).to have_content('Runner unassigned from project.')
- expect(new_runner_project).to have_content(project1.path)
+ expect(new_runner_project).to have_content(project1.name)
end
end
end
diff --git a/spec/features/explore/groups_spec.rb b/spec/features/explore/groups_spec.rb
index 458f83dffb4..57a7e8ea523 100644
--- a/spec/features/explore/groups_spec.rb
+++ b/spec/features/explore/groups_spec.rb
@@ -29,8 +29,8 @@ RSpec.describe 'Explore Groups', :js, feature_category: :subgroups do
shared_examples 'renders public and internal projects' do
it do
visit_page
- expect(page).to have_content(public_project.name)
- expect(page).to have_content(internal_project.name)
+ expect(page).to have_content(public_project.name).or(have_content(public_project.path))
+ expect(page).to have_content(internal_project.name).or(have_content(internal_project.path))
expect(page).not_to have_content(private_project.name)
end
end
@@ -38,7 +38,7 @@ RSpec.describe 'Explore Groups', :js, feature_category: :subgroups do
shared_examples 'renders only public project' do
it do
visit_page
- expect(page).to have_content(public_project.name)
+ expect(page).to have_content(public_project.name).or(have_content(public_project.path))
expect(page).not_to have_content(internal_project.name)
expect(page).not_to have_content(private_project.name)
end
@@ -47,7 +47,7 @@ RSpec.describe 'Explore Groups', :js, feature_category: :subgroups do
shared_examples 'renders group in public groups area' do
it do
visit explore_groups_path
- expect(page).to have_content(group.name)
+ expect(page).to have_content(group.path)
end
end
@@ -56,32 +56,44 @@ RSpec.describe 'Explore Groups', :js, feature_category: :subgroups do
sign_in(user)
end
- it_behaves_like 'renders public and internal projects' do
- subject(:visit_page) { visit group_path(group) }
+ context 'for group_path' do
+ it_behaves_like 'renders public and internal projects' do
+ subject(:visit_page) { visit group_path(group) }
+ end
end
- it_behaves_like 'renders public and internal projects' do
- subject(:visit_page) { visit issues_group_path(group) }
+ context 'for issues_group_path' do
+ it_behaves_like 'renders public and internal projects' do
+ subject(:visit_page) { visit issues_group_path(group) }
+ end
end
- it_behaves_like 'renders public and internal projects' do
- subject(:visit_page) { visit merge_requests_group_path(group) }
+ context 'for merge_requests_group_path' do
+ it_behaves_like 'renders public and internal projects' do
+ subject(:visit_page) { visit merge_requests_group_path(group) }
+ end
end
it_behaves_like 'renders group in public groups area'
end
context 'when signed out' do
- it_behaves_like 'renders only public project' do
- subject(:visit_page) { visit group_path(group) }
+ context 'for group_path' do
+ it_behaves_like 'renders only public project' do
+ subject(:visit_page) { visit group_path(group) }
+ end
end
- it_behaves_like 'renders only public project' do
- subject(:visit_page) { visit issues_group_path(group) }
+ context 'for issues_group_path' do
+ it_behaves_like 'renders only public project' do
+ subject(:visit_page) { visit issues_group_path(group) }
+ end
end
- it_behaves_like 'renders only public project' do
- subject(:visit_page) { visit merge_requests_group_path(group) }
+ context 'for merge_requests_group_path' do
+ it_behaves_like 'renders only public project' do
+ subject(:visit_page) { visit merge_requests_group_path(group) }
+ end
end
it_behaves_like 'renders group in public groups area'
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index bb61431d773..6443f4a6c38 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -74,7 +74,7 @@ RSpec.describe 'Edit group settings', feature_category: :subgroups do
visit new_project_full_path
expect(page).to have_current_path(new_project_full_path, ignore_query: true)
- expect(find('.breadcrumbs')).to have_content(project.path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
end
it 'the old project path redirects to the new path' do
@@ -82,7 +82,7 @@ RSpec.describe 'Edit group settings', feature_category: :subgroups do
visit old_project_full_path
expect(page).to have_current_path(new_project_full_path, ignore_query: true)
- expect(find('.breadcrumbs')).to have_content(project.path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
end
end
end
@@ -265,7 +265,7 @@ RSpec.describe 'Edit group settings', feature_category: :subgroups do
end
context 'with gitlab-profile project and no README.md' do
- let_it_be(:project) { create(:project, name: 'gitlab-profile', namespace: group) }
+ let_it_be(:project) { create(:project, path: 'gitlab-profile', namespace: group) }
it 'renders Add README button and allows user to create a README via the IDE' do
visit edit_group_path(group)
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index db069b194b5..7963d4c3b22 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe 'Group Packages', feature_category: :package_registry do
find('[data-testid="root-link"]', text: project.path).click
expect(page).to have_current_path(project_path(project))
- expect(page).to have_content(project.path)
+ expect(page).to have_content(project.name)
end
context 'sorting' do
diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 8082d1bdf63..9b9c2158432 100644
--- a/spec/features/projects/files/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -11,8 +11,7 @@ RSpec.describe "User browses files", :js, feature_category: :projects do
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, :repository, name: "Shop") }
- let(:project2) { create(:project, :repository, name: "Another Project", path: "another-project") }
+ let_it_be(:project) { create(:project, :repository) }
let(:tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:user) { project.first_owner }
@@ -142,7 +141,9 @@ RSpec.describe "User browses files", :js, feature_category: :projects do
expect(page).to have_current_path(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"), ignore_query: true)
expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
- click_link("shop")
+ page.within(".tree-ref-container") do
+ click_link(project.path)
+ end
page.within(".tree-table") do
click_link("README.md")
diff --git a/spec/features/projects/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb
index 28d5c080db9..6b646bcf7d3 100644
--- a/spec/features/projects/settings/forked_project_settings_spec.rb
+++ b/spec/features/projects/settings/forked_project_settings_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js, feature_catego
wait_for_requests
- fill_in('confirm_name_input', with: forked_project.name)
+ fill_in('confirm_name_input', with: forked_project.path)
click_button('Confirm')
wait_for_requests
diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb
index 85d50083c33..a6b72e7a297 100644
--- a/spec/features/projects/settings/user_renames_a_project_spec.rb
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe 'Projects > Settings > User renames a project', feature_category:
it 'shows errors for invalid project path' do
change_path(project, 'foo&bar')
- expect(page).to have_field 'Path', with: 'gitlab'
+ expect(page).to have_field 'Path', with: project.path
expect(page).to have_content "Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'"
end
end
diff --git a/spec/frontend/authentication/webauthn/authenticate_spec.js b/spec/frontend/authentication/webauthn/authenticate_spec.js
index b1f4e43e56d..b3a634fb072 100644
--- a/spec/frontend/authentication/webauthn/authenticate_spec.js
+++ b/spec/frontend/authentication/webauthn/authenticate_spec.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
-import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import htmlWebauthnAuthenticate from 'test_fixtures/webauthn/authenticate.html';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import waitForPromises from 'helpers/wait_for_promises';
import WebAuthnAuthenticate from '~/authentication/webauthn/authenticate';
import MockWebAuthnDevice from './mock_webauthn_device';
@@ -35,7 +36,7 @@ describe('WebAuthnAuthenticate', () => {
};
beforeEach(() => {
- loadHTMLFixture('webauthn/authenticate.html');
+ setHTMLFixture(htmlWebauthnAuthenticate);
fallbackElement = document.createElement('div');
fallbackElement.classList.add('js-2fa-form');
webAuthnDevice = new MockWebAuthnDevice();
diff --git a/spec/frontend/authentication/webauthn/register_spec.js b/spec/frontend/authentication/webauthn/register_spec.js
index 773481346fc..5f0691782a7 100644
--- a/spec/frontend/authentication/webauthn/register_spec.js
+++ b/spec/frontend/authentication/webauthn/register_spec.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
-import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import htmlWebauthnRegister from 'test_fixtures/webauthn/register.html';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { trimText } from 'helpers/text_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -25,7 +26,7 @@ describe('WebAuthnRegister', () => {
let component;
beforeEach(() => {
- loadHTMLFixture('webauthn/register.html');
+ setHTMLFixture(htmlWebauthnRegister);
webAuthnDevice = new MockWebAuthnDevice();
container = $('#js-register-token-2fa');
component = new WebAuthnRegister(container, {
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
index 7940518f1e8..1fa613d15d4 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -5,27 +5,31 @@ import {
GlSearchBoxByType,
GlLink,
} from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
import DropdownContentsLabelsView from '~/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue';
import LabelItem from '~/sidebar/components/labels/labels_select_vue/label_item.vue';
-
+import { stubComponent } from 'helpers/stub_component';
import * as actions from '~/sidebar/components/labels/labels_select_vue/store/actions';
import * as getters from '~/sidebar/components/labels/labels_select_vue/store/getters';
import mutations from '~/sidebar/components/labels/labels_select_vue/store/mutations';
import defaultState from '~/sidebar/components/labels/labels_select_vue/store/state';
-import { mockConfig, mockLabels, mockRegularLabel } from './mock_data';
+import { mockConfig, mockLabels } from './mock_data';
Vue.use(Vuex);
describe('DropdownContentsLabelsView', () => {
let wrapper;
+ let store;
+
+ const focusInputMock = jest.fn();
+ const updateSelectedLabelsMock = jest.fn();
+ const toggleDropdownContentsMock = jest.fn();
- const createComponent = (initialState = mockConfig) => {
- const store = new Vuex.Store({
+ const createComponent = (initialState = mockConfig, mountFn = shallowMountExtended) => {
+ store = new Vuex.Store({
getters,
mutations,
state: {
@@ -36,14 +40,20 @@ describe('DropdownContentsLabelsView', () => {
actions: {
...actions,
fetchLabels: jest.fn(),
+ updateSelectedLabels: updateSelectedLabelsMock,
+ toggleDropdownContents: toggleDropdownContentsMock,
},
});
store.dispatch('setInitialState', initialState);
- store.dispatch('receiveLabelsSuccess', mockLabels);
- wrapper = shallowMount(DropdownContentsLabelsView, {
+ wrapper = mountFn(DropdownContentsLabelsView, {
store,
+ stubs: {
+ GlSearchBoxByType: stubComponent(GlSearchBoxByType, {
+ methods: { focusInput: focusInputMock },
+ }),
+ },
});
};
@@ -51,44 +61,54 @@ describe('DropdownContentsLabelsView', () => {
createComponent();
});
- const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
- const findDropdownTitle = () => wrapper.find('[data-testid="dropdown-title"]');
- const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
+ const findDropdownContent = () => wrapper.findByTestId('dropdown-content');
+ const findDropdownTitle = () => wrapper.findByTestId('dropdown-title');
+ const findDropdownFooter = () => wrapper.findByTestId('dropdown-footer');
+ const findNoMatchingResults = () => wrapper.findByTestId('no-matching-results');
+ const findCreateLabelLink = () => wrapper.findByTestId('create-label-link');
+ const findLabelsList = () => wrapper.findByTestId('labels-list');
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
+ const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
+ const findLabelItems = () => wrapper.findAllComponents(LabelItem);
+
+ const setCurrentHighlightItem = (value) => {
+ let initialValue = -1;
+
+ while (initialValue < value) {
+ findLabelsList().trigger('keydown.down');
+ initialValue += 1;
+ }
+ };
describe('computed', () => {
describe('visibleLabels', () => {
- it('returns matching labels filtered with `searchKey`', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'bug',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(1);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
+ beforeEach(() => {
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
- it('returns matching labels with fuzzy filtering', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'bg',
- });
+ it('returns matching labels filtered with `searchKey`', async () => {
+ await findSearchBoxByType().vm.$emit('input', 'bug');
- expect(wrapper.vm.visibleLabels.length).toBe(2);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- expect(wrapper.vm.visibleLabels[1].title).toBe('Boog');
+ const labelItems = findLabelItems();
+ expect(labelItems).toHaveLength(1);
+ expect(labelItems.at(0).text()).toBe('Bug');
});
- it('returns all labels when `searchKey` is empty', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: '',
- });
+ it('returns matching labels with fuzzy filtering', async () => {
+ await findSearchBoxByType().vm.$emit('input', 'bg');
- expect(wrapper.vm.visibleLabels.length).toBe(mockLabels.length);
+ const labelItems = findLabelItems();
+ expect(labelItems).toHaveLength(2);
+ expect(labelItems.at(0).text()).toBe('Bug');
+ expect(labelItems.at(1).text()).toBe('Boog');
+ });
+
+ it('returns all labels when `searchKey` is empty', async () => {
+ await findSearchBoxByType().vm.$emit('input', '');
+
+ expect(findLabelItems()).toHaveLength(mockLabels.length);
});
});
@@ -102,17 +122,11 @@ describe('DropdownContentsLabelsView', () => {
`(
'returns $returnValue when searchKey is "$searchKey" and visibleLabels is $labelsDescription',
async ({ searchKey, labels, returnValue }) => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey,
- });
-
- wrapper.vm.$store.dispatch('receiveLabelsSuccess', labels);
+ store.dispatch('receiveLabelsSuccess', labels);
- await nextTick();
+ await findSearchBoxByType().vm.$emit('input', searchKey);
- expect(wrapper.vm.showNoMatchingResultsMessage).toBe(returnValue);
+ expect(findNoMatchingResults().isVisible()).toBe(returnValue);
},
);
});
@@ -121,171 +135,134 @@ describe('DropdownContentsLabelsView', () => {
describe('methods', () => {
const fakePreventDefault = jest.fn();
- describe('isLabelSelected', () => {
- it('returns true when provided `label` param is one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true);
- });
-
- it('returns false when provided `label` param is not one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockLabels[1])).toBe(false);
- });
- });
-
describe('handleComponentAppear', () => {
it('calls `focusInput` on searchInput field', async () => {
- wrapper.vm.$refs.searchInput.focusInput = jest.fn();
+ findIntersectionObserver().vm.$emit('appear');
- await wrapper.vm.handleComponentAppear();
+ await nextTick();
- expect(wrapper.vm.$refs.searchInput.focusInput).toHaveBeenCalled();
+ expect(focusInputMock).toHaveBeenCalled();
});
});
describe('handleComponentDisappear', () => {
- it('calls action `receiveLabelsSuccess` with empty array', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
+ it('calls action `receiveLabelsSuccess` with empty array', async () => {
+ jest.spyOn(store, 'dispatch');
- wrapper.vm.handleComponentDisappear();
+ await findIntersectionObserver().vm.$emit('disappear');
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
+ expect(store.dispatch).toHaveBeenCalledWith(expect.anything(), []);
});
});
describe('handleCreateLabelClick', () => {
- it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
- jest.spyOn(wrapper.vm, 'toggleDropdownContentsCreateView');
+ it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', async () => {
+ jest.spyOn(store, 'dispatch');
- wrapper.vm.handleCreateLabelClick();
+ await findCreateLabelLink().vm.$emit('click');
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- expect(wrapper.vm.toggleDropdownContentsCreateView).toHaveBeenCalled();
+ expect(store.dispatch).toHaveBeenCalledWith('receiveLabelsSuccess', []);
+ expect(store.dispatch).toHaveBeenCalledWith('toggleDropdownContentsCreateView');
});
});
describe('handleKeyDown', () => {
- it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: UP_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(0);
+ beforeEach(() => {
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
- it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+
+ expect(findLabelItems().at(1).classes()).toContain('is-focused');
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
+ await findLabelsList().trigger('keydown.up');
- expect(wrapper.vm.currentHighlightItem).toBe(2);
+ expect(findLabelItems().at(1).classes()).not.toContain('is-focused');
});
- it('resets the search text when the Enter key is pressed', () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- searchKey: 'bug',
- });
+ it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', async () => {
+ expect(findLabelItems().at(0).classes()).not.toContain('is-focused');
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- preventDefault: fakePreventDefault,
- });
+ await findLabelsList().trigger('keydown.down');
- expect(wrapper.vm.searchKey).toBe('');
- expect(fakePreventDefault).toHaveBeenCalled();
+ expect(findLabelItems().at(0).classes()).toContain('is-focused');
});
- it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 2,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- preventDefault: fakePreventDefault,
- });
+ it('resets the search text when the Enter key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+ await findSearchBoxByType().vm.$emit('input', 'bug');
+ await findLabelsList().trigger('keydown.enter', { preventDefault: fakePreventDefault });
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockLabels[2]]);
+ expect(findSearchBoxByType().props('value')).toBe('');
+ expect(fakePreventDefault).toHaveBeenCalled();
});
- it('calls action `toggleDropdownContents` when Esc key is pressed', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', async () => {
+ await setCurrentHighlightItem(2);
+ await findLabelsList().trigger('keydown.enter', { preventDefault: fakePreventDefault });
+
+ expect(updateSelectedLabelsMock).toHaveBeenCalledWith(expect.anything(), [mockLabels[2]]);
+ });
- wrapper.vm.handleKeyDown({
- keyCode: ESC_KEY_CODE,
- });
+ it('calls action `toggleDropdownContents` when Esc key is pressed', async () => {
+ await setCurrentHighlightItem(1);
+ await findLabelsList().trigger('keydown.esc');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
+ expect(toggleDropdownContentsMock).toHaveBeenCalled();
});
- it('calls action `scrollIntoViewIfNeeded` in next tick when any key is pressed', async () => {
- jest.spyOn(wrapper.vm, 'scrollIntoViewIfNeeded').mockImplementation();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 1,
- });
+ it('calls action `scrollIntoViewIfNeeded` in next tick when esc key is pressed', async () => {
+ const containerTop = 500;
+ const labelTop = 0;
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
+ jest
+ .spyOn(findDropdownContent().element, 'getBoundingClientRect')
+ .mockReturnValueOnce({ top: containerTop });
- await nextTick();
- expect(wrapper.vm.scrollIntoViewIfNeeded).toHaveBeenCalled();
+ await setCurrentHighlightItem(1);
+ await findLabelsList().trigger('keydown.esc');
+
+ expect(findDropdownContent().element.scrollTop).toBe(labelTop - containerTop);
});
});
describe('handleLabelClick', () => {
beforeEach(() => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
+ createComponent(undefined, mountExtended);
+ store.dispatch('receiveLabelsSuccess', mockLabels);
});
it('calls action `updateSelectedLabels` with provided `label` param', () => {
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ findLabelItems().at(0).findComponent(GlLink).vm.$emit('click');
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockRegularLabel]);
+ expect(updateSelectedLabelsMock).toHaveBeenCalledWith(expect.anything(), [
+ { ...mockLabels[0], indeterminate: expect.anything(), set: expect.anything() },
+ ]);
});
it('calls action `toggleDropdownContents` when `state.allowMultiselect` is false', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents');
- wrapper.vm.$store.state.allowMultiselect = false;
+ store.state.allowMultiselect = false;
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ findLabelItems().at(0).findComponent(GlLink).vm.$emit('click');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
+ expect(toggleDropdownContentsMock).toHaveBeenCalled();
});
});
});
describe('template', () => {
+ beforeEach(() => {
+ store.dispatch('receiveLabelsSuccess', mockLabels);
+ });
+
it('renders gl-intersection-observer as component root', () => {
expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(true);
});
it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', async () => {
- wrapper.vm.$store.dispatch('requestLabels');
+ store.dispatch('requestLabels');
await nextTick();
const loadingIconEl = findLoadingIcon();
@@ -325,30 +302,19 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders label elements for all labels', () => {
- expect(wrapper.findAllComponents(LabelItem)).toHaveLength(mockLabels.length);
+ expect(findLabelItems()).toHaveLength(mockLabels.length);
});
it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- currentHighlightItem: 0,
- });
+ await setCurrentHighlightItem(0);
- await nextTick();
const labelItemEl = findDropdownContent().findComponent(LabelItem);
expect(labelItemEl.attributes('highlight')).toBe('true');
});
it('renders element containing "No matching results" when `searchKey` does not match with any label', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- searchKey: 'abc',
- });
-
- await nextTick();
+ await findSearchBoxByType().vm.$emit('input', 'abc');
const noMatchEl = findDropdownContent().find('li');
expect(noMatchEl.isVisible()).toBe(true);
@@ -356,7 +322,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders empty content while loading', async () => {
- wrapper.vm.$store.state.labelsFetchInProgress = true;
+ store.state.labelsFetchInProgress = true;
await nextTick();
const dropdownContent = findDropdownContent();
@@ -380,7 +346,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('does not render "Create label" footer link when `state.allowLabelCreate` is `false`', async () => {
- wrapper.vm.$store.state.allowLabelCreate = false;
+ store.state.allowLabelCreate = false;
await nextTick();
const createLabelLink = findDropdownFooter().findAllComponents(GlLink).at(0);
diff --git a/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb b/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
index 44147987ebb..0485796fe56 100644
--- a/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
+++ b/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
@@ -20,6 +20,10 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject, feature_category: :cont
mutation.resolve(**mutation_args)
end
+ before do
+ stub_feature_flags(frozen_outbound_job_token_scopes_override: false)
+ end
+
context 'when user is not logged in' do
let(:current_user) { nil }
@@ -43,10 +47,10 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject, feature_category: :cont
target_project.add_guest(current_user)
end
- it 'adds target project to the outbound job token scope by default' do
+ it 'adds target project to the inbound job token scope by default' do
expect do
expect(subject).to include(ci_job_token_scope: be_present, errors: be_empty)
- end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ end.to change { Ci::JobToken::ProjectScopeLink.inbound.count }.by(1)
end
context 'when mutation uses the direction argument' do
@@ -55,10 +59,8 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject, feature_category: :cont
context 'when targeting the outbound allowlist' do
let(:direction) { :outbound }
- it 'adds the target project' do
- expect do
- expect(subject).to include(ci_job_token_scope: be_present, errors: be_empty)
- end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ it 'raises an error' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
end
@@ -73,6 +75,42 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject, feature_category: :cont
end
end
+ context 'when FF frozen_outbound_job_token_scopes is disabled' do
+ before do
+ stub_feature_flags(frozen_outbound_job_token_scopes: false)
+ end
+
+ it 'adds target project to the outbound job token scope by default' do
+ expect do
+ expect(subject).to include(ci_job_token_scope: be_present, errors: be_empty)
+ end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ end
+
+ context 'when mutation uses the direction argument' do
+ let(:mutation_args) { super().merge!(direction: direction) }
+
+ context 'when targeting the outbound allowlist' do
+ let(:direction) { :outbound }
+
+ it 'adds the target project' do
+ expect do
+ expect(subject).to include(ci_job_token_scope: be_present, errors: be_empty)
+ end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ end
+ end
+
+ context 'when targeting the inbound allowlist' do
+ let(:direction) { :inbound }
+
+ it 'adds the target project' do
+ expect do
+ expect(subject).to include(ci_job_token_scope: be_present, errors: be_empty)
+ end.to change { Ci::JobToken::ProjectScopeLink.inbound.count }.by(1)
+ end
+ end
+ end
+ end
+
context 'when the service returns an error' do
let(:service) { double(:service) }
@@ -81,7 +119,7 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject, feature_category: :cont
project,
current_user
).and_return(service)
- expect(service).to receive(:execute).with(target_project, direction: :outbound).and_return(ServiceResponse.error(message: 'The error message'))
+ expect(service).to receive(:execute).with(target_project, direction: :inbound).and_return(ServiceResponse.error(message: 'The error message'))
expect(subject.fetch(:ci_job_token_scope)).to be_nil
expect(subject.fetch(:errors)).to include("The error message")
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index ae84331dcdb..ce2c6d0477b 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -451,7 +451,7 @@ RSpec.describe ApplicationHelper do
find_file: nil,
group: nil,
project_id: project.id,
- project: project.name,
+ project: project.path,
namespace_id: project.namespace.id
}
)
@@ -469,7 +469,7 @@ RSpec.describe ApplicationHelper do
find_file: nil,
group: project.group.name,
project_id: project.id,
- project: project.name,
+ project: project.path,
namespace_id: project.namespace.id
}
)
@@ -495,7 +495,7 @@ RSpec.describe ApplicationHelper do
find_file: nil,
group: nil,
project_id: issue.project.id,
- project: issue.project.name,
+ project: issue.project.path,
namespace_id: issue.project.namespace.id
}
)
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index e8e981251e3..600131270c6 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -62,19 +62,19 @@ RSpec.describe LabelsHelper do
end
context 'with a project as subject' do
- let(:namespace) { build(:namespace, name: 'foo3') }
- let(:subject) { build(:project, namespace: namespace, name: 'bar3') }
+ let(:namespace) { build(:namespace) }
+ let(:subject) { build(:project, namespace: namespace) }
it 'links to project issues page' do
- expect(link_to_label(label_presenter)).to match %r{<a.*href="/foo3/bar3/-/issues\?label_name%5B%5D=#{label.name}".*>.*</a>}m
+ expect(link_to_label(label_presenter)).to match %r{<a.*href="/#{subject.full_path}/-/issues\?label_name%5B%5D=#{label.name}".*>.*</a>}m
end
end
context 'with a group as subject' do
- let(:subject) { build(:group, name: 'bar') }
+ let(:subject) { build(:group) }
it 'links to group issues page' do
- expect(link_to_label(label_presenter)).to match %r{<a.*href="/groups/bar/-/issues\?label_name%5B%5D=#{label.name}".*>.*</a>}m
+ expect(link_to_label(label_presenter)).to match %r{<a.*href="/groups/#{subject.path}/-/issues\?label_name%5B%5D=#{label.name}".*>.*</a>}m
end
end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index 9b01622bd17..a0bd8df81cc 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -38,30 +38,6 @@ RSpec.describe MergeRequestsHelper, feature_category: :code_review_workflow do
subject { diffs_tab_pane_data(project, merge_request, {}) }
context 'for endpoint_diff_for_path' do
- context 'when default project namespace' do
- let_it_be(:project) { create(:project) }
- let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
-
- it 'returns expected values' do
- expect(
- subject[:endpoint_diff_for_path]
- ).to eq("/#{project.full_path}/-/merge_requests/#{merge_request.iid}/diff_for_path.json")
- end
- end
-
- context 'when group project namespace' do
- let_it_be(:group) { create(:group, :public) }
- let_it_be(:project) { create(:project, :private, group: group) }
- let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
-
- it 'returns expected values' do
- namespace = "#{group.name}/#{project.name}"
- expect(
- subject[:endpoint_diff_for_path]
- ).to include("/#{namespace}/-/merge_requests/#{merge_request.iid}/diff_for_path.json")
- end
- end
-
context 'when sub-group project namespace' do
let_it_be(:group) { create(:group, :public) }
let_it_be(:subgroup) { create(:group, :private, parent: group) }
@@ -69,32 +45,21 @@ RSpec.describe MergeRequestsHelper, feature_category: :code_review_workflow do
let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
it 'returns expected values' do
- namespace = "#{group.name}/#{subgroup.name}/#{project.name}"
- expect(
- subject[:endpoint_diff_for_path]
- ).to include("#{namespace}/-/merge_requests/#{merge_request.iid}/diff_for_path.json")
- end
- end
-
- context 'when sub-sub-group project namespace' do
- let_it_be(:group) { create(:group, :public) }
- let_it_be(:subgroup) { create(:group, :private, parent: group) }
- let_it_be(:subsubgroup) { create(:group, :private, parent: subgroup) }
- let_it_be(:project) { create(:project, :private, group: subsubgroup) }
- let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
-
- it 'returns expected values' do
- namespace = "#{group.name}/#{subgroup.name}/#{subsubgroup.name}/#{project.name}"
expect(
subject[:endpoint_diff_for_path]
- ).to include("#{namespace}/-/merge_requests/#{merge_request.iid}/diff_for_path.json")
+ ).to include("#{project.full_path}/-/merge_requests/#{merge_request.iid}/diff_for_path.json")
end
end
end
end
describe '#merge_path_description' do
- let_it_be(:project) { create(:project) }
+ # Using let_it_be(:project) raises the following error, so we use need to use let(:project):
+ # ActiveRecord::InvalidForeignKey:
+ # PG::ForeignKeyViolation: ERROR: insert or update on table "fork_network_members" violates foreign key
+ # constraint "fk_rails_a40860a1ca"
+ # DETAIL: Key (fork_network_id)=(8) is not present in table "fork_networks".
+ let(:project) { create(:project) }
let(:forked_project) { fork_project(project) }
let(:merge_request_forked) { create(:merge_request, source_project: forked_project, target_project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
diff --git a/spec/lib/api/entities/project_job_token_scope_spec.rb b/spec/lib/api/entities/project_job_token_scope_spec.rb
new file mode 100644
index 00000000000..cceef9e7f30
--- /dev/null
+++ b/spec/lib/api/entities/project_job_token_scope_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::API::Entities::ProjectJobTokenScope, feature_category: :secrets_management do
+ let_it_be(:project) do
+ create(:project,
+ :public,
+ ci_inbound_job_token_scope_enabled: true,
+ ci_outbound_job_token_scope_enabled: true
+ )
+ end
+
+ let_it_be(:current_user) { create(:user) }
+
+ let(:options) { { current_user: current_user } }
+ let(:entity) { described_class.new(project, options) }
+
+ describe "#as_json" do
+ subject { entity.as_json }
+
+ it 'includes basic fields' do
+ expect(subject).to eq(
+ inbound_enabled: true,
+ outbound_enabled: true
+ )
+ end
+
+ it 'includes basic fields' do
+ project.update!(ci_inbound_job_token_scope_enabled: false)
+
+ expect(subject).to eq(
+ inbound_enabled: false,
+ outbound_enabled: true
+ )
+ end
+ end
+end
diff --git a/spec/lib/container_registry/path_spec.rb b/spec/lib/container_registry/path_spec.rb
index aa6876225b5..c9fa3ec690b 100644
--- a/spec/lib/container_registry/path_spec.rb
+++ b/spec/lib/container_registry/path_spec.rb
@@ -143,8 +143,8 @@ RSpec.describe ContainerRegistry::Path do
let(:path) { 'some_group/some_project' }
before do
- create(:project, group: group, name: 'some_project')
- create(:project, name: 'some_project')
+ create(:project, group: group, path: 'some_project')
+ create(:project, path: 'some_project')
end
it 'returns a correct project' do
@@ -162,7 +162,7 @@ RSpec.describe ContainerRegistry::Path do
context 'when matching multi-level path' do
let(:project) do
- create(:project, group: group, name: 'some_project')
+ create(:project, group: group, path: 'some_project')
end
context 'when using the zero-level path' do
@@ -212,7 +212,7 @@ RSpec.describe ContainerRegistry::Path do
let(:group) { create(:group, path: 'Some_Group') }
before do
- create(:project, group: group, name: 'some_project')
+ create(:project, group: group, path: 'some_project')
end
context 'when project path equal repository path' do
@@ -255,7 +255,7 @@ RSpec.describe ContainerRegistry::Path do
let(:group) { create(:group, path: 'SomeGroup') }
before do
- create(:project, group: group, name: 'MyProject')
+ create(:project, group: group, path: 'MyProject')
end
it 'returns downcased project path' do
diff --git a/spec/lib/gitlab/ci/config/external/mapper/verifier_spec.rb b/spec/lib/gitlab/ci/config/external/mapper/verifier_spec.rb
index ef5049158c1..fa675950fc1 100644
--- a/spec/lib/gitlab/ci/config/external/mapper/verifier_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/mapper/verifier_spec.rb
@@ -380,55 +380,5 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Verifier, feature_category:
end
end
end
-
- context 'when FF ci_fix_max_includes is disabled' do
- before do
- stub_feature_flags(ci_fix_max_includes: false)
- end
-
- context 'when total file count exceeds max_includes' do
- context 'when files are nested' do
- let(:files) do
- [
- Gitlab::Ci::Config::External::File::Local.new({ local: 'nested_configs.yml' }, context)
- ]
- end
-
- it 'raises Processor::IncludeError' do
- allow(context).to receive(:max_includes).and_return(1)
- expect { process }.to raise_error(Gitlab::Ci::Config::External::Processor::IncludeError)
- end
- end
-
- context 'when files are not nested' do
- let(:files) do
- [
- Gitlab::Ci::Config::External::File::Local.new({ local: 'myfolder/file1.yml' }, context),
- Gitlab::Ci::Config::External::File::Local.new({ local: 'myfolder/file2.yml' }, context)
- ]
- end
-
- it 'raises Mapper::TooManyIncludesError' do
- allow(context).to receive(:max_includes).and_return(1)
- expect { process }.to raise_error(Gitlab::Ci::Config::External::Mapper::TooManyIncludesError)
- end
- end
-
- context 'when files are duplicates' do
- let(:files) do
- [
- Gitlab::Ci::Config::External::File::Local.new({ local: 'myfolder/file1.yml' }, context),
- Gitlab::Ci::Config::External::File::Local.new({ local: 'myfolder/file1.yml' }, context),
- Gitlab::Ci::Config::External::File::Local.new({ local: 'myfolder/file1.yml' }, context)
- ]
- end
-
- it 'raises error' do
- allow(context).to receive(:max_includes).and_return(2)
- expect { process }.to raise_error(Gitlab::Ci::Config::External::Mapper::TooManyIncludesError)
- end
- end
- end
- end
end
end
diff --git a/spec/lib/gitlab/consul/internal_spec.rb b/spec/lib/gitlab/consul/internal_spec.rb
index 28dcaac9ff2..ff76269fe76 100644
--- a/spec/lib/gitlab/consul/internal_spec.rb
+++ b/spec/lib/gitlab/consul/internal_spec.rb
@@ -77,9 +77,11 @@ RSpec.describe Gitlab::Consul::Internal do
shared_examples 'returns nil given blank value of' do |input_symbol|
[nil, ''].each do |value|
- let(input_symbol) { value }
+ context "with #{value}" do
+ let(input_symbol) { value }
- it { is_expected.to be_nil }
+ it { is_expected.to be_nil }
+ end
end
end
diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb
index f13d98ec9b9..bb68bca5dfa 100644
--- a/spec/lib/gitlab/email/message/repository_push_spec.rb
+++ b/spec/lib/gitlab/email/message/repository_push_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe Gitlab::Email::Message::RepositoryPush do
describe '#project_name_with_namespace' do
subject { message.project_name_with_namespace }
- it { is_expected.to eq "#{group.name} / #{project.path}" }
+ it { is_expected.to eq "#{group.name} / #{project.name}" }
end
describe '#author' do
diff --git a/spec/lib/gitlab/import_export/project/export_task_spec.rb b/spec/lib/gitlab/import_export/project/export_task_spec.rb
index 3dd1e9257cc..95971d08175 100644
--- a/spec/lib/gitlab/import_export/project/export_task_spec.rb
+++ b/spec/lib/gitlab/import_export/project/export_task_spec.rb
@@ -10,14 +10,14 @@ RSpec.describe Gitlab::ImportExport::Project::ExportTask, :silence_stdout do
let(:measurement_enabled) { false }
let(:file_path) { 'spec/fixtures/gitlab/import_export/test_project_export.tar.gz' }
let(:project) { create(:project, creator: user, namespace: user.namespace) }
- let(:project_name) { project.name }
+ let(:project_path) { project.path }
let(:rake_task) { described_class.new(task_params) }
let(:task_params) do
{
username: username,
namespace_path: namespace_path,
- project_path: project_name,
+ project_path: project_path,
file_path: file_path,
measurement_enabled: measurement_enabled
}
@@ -48,10 +48,10 @@ RSpec.describe Gitlab::ImportExport::Project::ExportTask, :silence_stdout do
end
context 'when project is not found' do
- let(:project_name) { 'invalid project name' }
+ let(:project_path) { 'invalid project path' }
it 'logs an error' do
- expect { subject }.to output(/Project with path: #{project_name} was not found. Please provide correct project path/).to_stdout
+ expect { subject }.to output(/Project with path: #{project_path} was not found. Please provide correct project path/).to_stdout
end
it 'returns false' do
diff --git a/spec/lib/gitlab/redis/cluster_rate_limiting_spec.rb b/spec/lib/gitlab/redis/cluster_rate_limiting_spec.rb
deleted file mode 100644
index 3eba3233f08..00000000000
--- a/spec/lib/gitlab/redis/cluster_rate_limiting_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Redis::ClusterRateLimiting, feature_category: :redis do
- include_examples "redis_new_instance_shared_examples", 'cluster_rate_limiting', Gitlab::Redis::Cache
-end
diff --git a/spec/mailers/emails/pages_domains_spec.rb b/spec/mailers/emails/pages_domains_spec.rb
index cf17f2e5ebf..ff446b83412 100644
--- a/spec/mailers/emails/pages_domains_spec.rb
+++ b/spec/mailers/emails/pages_domains_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe Emails::PagesDomains do
end
describe '#pages_domain_enabled_email' do
- let(:email_subject) { "#{project.path} | GitLab Pages domain '#{domain.domain}' has been enabled" }
+ let(:email_subject) { "#{project.name} | GitLab Pages domain '#{domain.domain}' has been enabled" }
let(:link_anchor) { 'steps' }
subject { Notify.pages_domain_enabled_email(domain, user) }
@@ -69,7 +69,7 @@ RSpec.describe Emails::PagesDomains do
end
describe '#pages_domain_disabled_email' do
- let(:email_subject) { "#{project.path} | GitLab Pages domain '#{domain.domain}' has been disabled" }
+ let(:email_subject) { "#{project.name} | GitLab Pages domain '#{domain.domain}' has been disabled" }
let(:link_anchor) { '4-verify-the-domains-ownership' }
subject { Notify.pages_domain_disabled_email(domain, user) }
@@ -82,7 +82,7 @@ RSpec.describe Emails::PagesDomains do
end
describe '#pages_domain_verification_succeeded_email' do
- let(:email_subject) { "#{project.path} | Verification succeeded for GitLab Pages domain '#{domain.domain}'" }
+ let(:email_subject) { "#{project.name} | Verification succeeded for GitLab Pages domain '#{domain.domain}'" }
let(:link_anchor) { 'steps' }
subject { Notify.pages_domain_verification_succeeded_email(domain, user) }
@@ -93,7 +93,7 @@ RSpec.describe Emails::PagesDomains do
end
describe '#pages_domain_verification_failed_email' do
- let(:email_subject) { "#{project.path} | ACTION REQUIRED: Verification failed for GitLab Pages domain '#{domain.domain}'" }
+ let(:email_subject) { "#{project.name} | ACTION REQUIRED: Verification failed for GitLab Pages domain '#{domain.domain}'" }
let(:link_anchor) { 'steps' }
subject { Notify.pages_domain_verification_failed_email(domain, user) }
@@ -104,7 +104,7 @@ RSpec.describe Emails::PagesDomains do
end
describe '#pages_domain_auto_ssl_failed_email' do
- let(:email_subject) { "#{project.path} | ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '#{domain.domain}'" }
+ let(:email_subject) { "#{project.name} | ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '#{domain.domain}'" }
subject { Notify.pages_domain_auto_ssl_failed_email(domain, user) }
diff --git a/spec/models/design_management/design_spec.rb b/spec/models/design_management/design_spec.rb
index cb122fa09fc..52bb23588e3 100644
--- a/spec/models/design_management/design_spec.rb
+++ b/spec/models/design_management/design_spec.rb
@@ -514,9 +514,9 @@ RSpec.describe DesignManagement::Design, feature_category: :design_management do
describe '#to_reference' do
let(:filename) { 'homescreen.jpg' }
- let(:namespace) { build(:namespace, id: non_existing_record_id, path: 'sample-namespace') }
- let(:project) { build(:project, name: 'sample-project', namespace: namespace) }
- let(:group) { build(:group, name: 'Group', path: 'sample-group') }
+ let(:namespace) { build(:namespace, id: non_existing_record_id) }
+ let(:project) { build(:project, namespace: namespace) }
+ let(:group) { build(:group) }
let(:issue) { build(:issue, iid: 1, project: project) }
let(:design) { build(:design, filename: filename, issue: issue, project: project) }
@@ -536,7 +536,7 @@ RSpec.describe DesignManagement::Design, feature_category: :design_management do
design.to_reference(group, full: true)
]
- expect(refs).to all(eq 'sample-namespace/sample-project#1/designs[homescreen.jpg]')
+ expect(refs).to all(eq "#{project.full_path}#1/designs[homescreen.jpg]")
end
end
@@ -547,7 +547,7 @@ RSpec.describe DesignManagement::Design, feature_category: :design_management do
design.to_reference(group, full: false)
]
- expect(refs).to all(eq 'sample-namespace/sample-project#1[homescreen.jpg]')
+ expect(refs).to all(eq "#{project.full_path}#1[homescreen.jpg]")
end
end
@@ -596,7 +596,7 @@ RSpec.describe DesignManagement::Design, feature_category: :design_management do
'url_filename' => filename,
'issue' => issue.iid.to_s,
'namespace' => design.project.namespace.to_param,
- 'project' => design.project.name
+ 'project' => design.project.to_param
)
end
diff --git a/spec/models/integrations/chat_message/deployment_message_spec.rb b/spec/models/integrations/chat_message/deployment_message_spec.rb
index 8da27ef5aa0..d16c191bd08 100644
--- a/spec/models/integrations/chat_message/deployment_message_spec.rb
+++ b/spec/models/integrations/chat_message/deployment_message_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Integrations::ChatMessage::DeploymentMessage do
let_it_be(:user) { create(:user, name: 'John Smith', username: 'smith') }
let_it_be(:namespace) { create(:namespace, name: 'myspace') }
- let_it_be(:project) { create(:project, :repository, namespace: namespace, name: 'myproject') }
+ let_it_be(:project) { create(:project, :repository, namespace: namespace, path: 'myproject') }
let_it_be(:commit) { project.commit('HEAD') }
let_it_be(:ci_build) { create(:ci_build, project: project) }
let_it_be(:environment) { create(:environment, name: 'myenvironment', project: project) }
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 38f50f7627e..cf48a602104 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -590,8 +590,8 @@ RSpec.describe Issue, feature_category: :team_planning do
end
describe '#to_reference' do
- let_it_be(:namespace) { create(:namespace, path: 'sample-namespace') }
- let_it_be(:project) { create(:project, name: 'sample-project', namespace: namespace) }
+ let_it_be(:namespace) { create(:namespace) }
+ let_it_be(:project) { create(:project, namespace: namespace) }
let_it_be(:issue) { create(:issue, project: project) }
context 'when nil argument' do
@@ -617,17 +617,17 @@ RSpec.describe Issue, feature_category: :team_planning do
context 'when cross-project in same namespace' do
let(:another_project) do
- create(:project, name: 'another-project', namespace: project.namespace)
+ create(:project, namespace: project.namespace)
end
it 'returns a cross-project reference' do
- expect(issue.to_reference(another_project)).to eq "sample-project##{issue.iid}"
+ expect(issue.to_reference(another_project)).to eq "#{project.path}##{issue.iid}"
end
end
context 'when cross-project in different namespace' do
let(:another_namespace) { build(:namespace, id: non_existing_record_id, path: 'another-namespace') }
- let(:another_namespace_project) { build(:project, path: 'another-project', namespace: another_namespace) }
+ let(:another_namespace_project) { build(:project, namespace: another_namespace) }
it 'returns complete path to the issue' do
expect(issue.to_reference(another_namespace_project)).to eq "#{project.full_path}##{issue.iid}"
@@ -638,7 +638,7 @@ RSpec.describe Issue, feature_category: :team_planning do
context 'when argument is a namespace' do
context 'when same as issue' do
it 'returns path to the issue with the project name' do
- expect(issue.to_reference(namespace)).to eq "sample-project##{issue.iid}"
+ expect(issue.to_reference(namespace)).to eq "#{project.path}##{issue.iid}"
end
it 'returns full reference with full: true' do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index a66302da6f5..6cd4b9e0753 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1049,7 +1049,7 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end
describe '#to_reference' do
- let(:project) { build(:project, name: 'sample-project') }
+ let(:project) { build(:project) }
let(:merge_request) { build(:merge_request, target_project: project, iid: 1) }
it 'returns a String reference to the object' do
@@ -1057,12 +1057,12 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
- expect(merge_request.to_reference(another_project)).to eq "sample-project!1"
+ another_project = build(:project, namespace: project.namespace)
+ expect(merge_request.to_reference(another_project)).to eq "#{project.path}!1"
end
it 'returns a String reference with the full path' do
- expect(merge_request.to_reference(full: true)).to eq(project.full_path + '!1')
+ expect(merge_request.to_reference(full: true)).to eq("#{project.full_path}!1")
end
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 9f6b1f8016b..8bd7c057a6e 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -439,8 +439,8 @@ RSpec.describe Milestone do
describe '#to_reference' do
let(:group) { build_stubbed(:group) }
- let(:project) { build_stubbed(:project, name: 'sample-project') }
- let(:another_project) { build_stubbed(:project, name: 'another-project', namespace: project.namespace) }
+ let(:project) { build_stubbed(:project, path: 'sample-project') }
+ let(:another_project) { build_stubbed(:project, path: 'another-project', namespace: project.namespace) }
context 'for a project milestone' do
let(:milestone) { build_stubbed(:milestone, iid: 1, project: project, name: 'milestone') }
diff --git a/spec/models/operations/feature_flag_spec.rb b/spec/models/operations/feature_flag_spec.rb
index dd1ff95a16d..4a39c5dc234 100644
--- a/spec/models/operations/feature_flag_spec.rb
+++ b/spec/models/operations/feature_flag_spec.rb
@@ -37,8 +37,8 @@ RSpec.describe Operations::FeatureFlag do
end
describe '#to_reference' do
- let(:namespace) { build(:namespace, path: 'sample-namespace') }
- let(:project) { build(:project, name: 'sample-project', namespace: namespace) }
+ let(:namespace) { build(:namespace) }
+ let(:project) { build(:project, namespace: namespace) }
let(:feature_flag) { build(:operations_feature_flag, iid: 1, project: project) }
it 'returns feature flag id' do
@@ -46,7 +46,7 @@ RSpec.describe Operations::FeatureFlag do
end
it 'returns complete path to the feature flag with full: true' do
- expect(feature_flag.to_reference(full: true)).to eq '[feature_flag:sample-namespace/sample-project/1]'
+ expect(feature_flag.to_reference(full: true)).to eq "[feature_flag:#{project.full_path}/1]"
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 00a94c80198..92849efc462 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -788,7 +788,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do
let(:new_project) do
build(:project,
- name: project_pending_deletion.name,
+ path: project_pending_deletion.path,
namespace: project_pending_deletion.namespace)
end
@@ -1692,7 +1692,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do
context 'with namespace' do
before do
@group = create(:group, name: 'gitlab')
- @project = create(:project, name: 'gitlabhq', namespace: @group)
+ @project = create(:project, path: 'gitlabhq', namespace: @group)
end
it { expect(@project.to_param).to eq('gitlabhq') }
@@ -7995,7 +7995,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do
describe '#activity_path' do
it 'returns the project activity_path' do
- expected_path = "/#{project.namespace.path}/#{project.name}/activity"
+ expected_path = "/#{project.full_path}/activity"
expect(project.activity_path).to eq(expected_path)
end
diff --git a/spec/models/service_desk_setting_spec.rb b/spec/models/service_desk_setting_spec.rb
index dba33e829c6..b9679b82bd0 100644
--- a/spec/models/service_desk_setting_spec.rb
+++ b/spec/models/service_desk_setting_spec.rb
@@ -82,8 +82,8 @@ RSpec.describe ServiceDeskSetting, feature_category: :service_desk do
# group1/test/one and group1/test-one will both have 'group-test-one' slug
let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group, name: 'test') }
- let_it_be(:project1) { create(:project, name: 'test-one', group: group) }
- let_it_be(:project2) { create(:project, name: 'one', group: subgroup) }
+ let_it_be(:project1) { create(:project, path: 'test-one', group: group) }
+ let_it_be(:project2) { create(:project, path: 'one', group: subgroup) }
let_it_be(:project_key) { 'key' }
let!(:setting) do
create(:service_desk_setting, project: project1, project_key: project_key)
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index da1f2653676..495c409f7b5 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -145,7 +145,7 @@ RSpec.describe Snippet do
describe '#to_reference' do
context 'when snippet belongs to a project' do
- let(:project) { build(:project, name: 'sample-project') }
+ let(:project) { build(:project) }
let(:snippet) { build(:snippet, id: 1, project: project) }
it 'returns a String reference to the object' do
@@ -153,8 +153,8 @@ RSpec.describe Snippet do
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
- expect(snippet.to_reference(another_project)).to eq "sample-project$1"
+ another_project = build(:project, namespace: project.namespace)
+ expect(snippet.to_reference(another_project)).to eq "#{project.path}$1"
end
end
@@ -166,7 +166,7 @@ RSpec.describe Snippet do
end
it 'still returns shortest reference when project arg present' do
- another_project = build(:project, name: 'another-project')
+ another_project = build(:project)
expect(snippet.to_reference(another_project)).to eq "$1"
end
end
diff --git a/spec/presenters/project_hook_presenter_spec.rb b/spec/presenters/project_hook_presenter_spec.rb
index a85865652d8..7c02548af08 100644
--- a/spec/presenters/project_hook_presenter_spec.rb
+++ b/spec/presenters/project_hook_presenter_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe ProjectHookPresenter do
subject { web_hook.present.logs_details_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}"
+ "/#{project.full_path}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}"
end
it { is_expected.to eq(expected_path) }
@@ -21,7 +21,7 @@ RSpec.describe ProjectHookPresenter do
subject { web_hook.present.logs_retry_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}/retry"
+ "/#{project.full_path}/-/hooks/#{web_hook.id}/hook_logs/#{web_hook_log.id}/retry"
end
it { is_expected.to eq(expected_path) }
diff --git a/spec/presenters/service_hook_presenter_spec.rb b/spec/presenters/service_hook_presenter_spec.rb
index c7703593327..48c3f6f0a22 100644
--- a/spec/presenters/service_hook_presenter_spec.rb
+++ b/spec/presenters/service_hook_presenter_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe ServiceHookPresenter do
subject { service_hook.present.logs_details_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/settings/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}"
+ "/#{project.full_path}/-/settings/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}"
end
it { is_expected.to eq(expected_path) }
@@ -22,7 +22,7 @@ RSpec.describe ServiceHookPresenter do
subject { service_hook.present.logs_retry_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/settings/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}/retry"
+ "/#{project.full_path}/-/settings/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}/retry"
end
it { is_expected.to eq(expected_path) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
index 55e728b2141..8791d793cb4 100644
--- a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
@@ -53,14 +53,29 @@ RSpec.describe 'CiJobTokenScopeAddProject', feature_category: :continuous_integr
before do
target_project.add_developer(current_user)
+ stub_feature_flags(frozen_outbound_job_token_scopes_override: false)
end
- it 'adds the target project to the job token scope' do
+ it 'adds the target project to the inbound job token scope' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response.dig('ciJobTokenScope', 'projects', 'nodes')).not_to be_empty
- end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ end.to change { Ci::JobToken::ProjectScopeLink.inbound.count }.by(1)
+ end
+
+ context 'when FF frozen_outbound_job_token_scopes is disabled' do
+ before do
+ stub_feature_flags(frozen_outbound_job_token_scopes: false)
+ end
+
+ it 'adds the target project to the outbound job token scope' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response.dig('ciJobTokenScope', 'projects', 'nodes')).not_to be_empty
+ end.to change { Ci::JobToken::ProjectScopeLink.outbound.count }.by(1)
+ end
end
context 'when invalid target project is provided' do
diff --git a/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb b/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
index 0951d165d46..79e86c1f2af 100644
--- a/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
@@ -5,6 +5,10 @@ require 'spec_helper'
RSpec.describe 'ProjectCiCdSettingsUpdate', feature_category: :continuous_integration do
include GraphqlHelpers
+ before do
+ stub_feature_flags(frozen_outbound_job_token_scopes_override: false)
+ end
+
let_it_be(:project) do
create(:project,
keep_latest_artifact: true,
@@ -61,7 +65,7 @@ RSpec.describe 'ProjectCiCdSettingsUpdate', feature_category: :continuous_integr
expect(project.keep_latest_artifact).to eq(false)
end
- it 'updates job_token_scope_enabled' do
+ it 'allows setting job_token_scope_enabled to false' do
post_graphql_mutation(mutation, current_user: user)
project.reload
@@ -70,6 +74,51 @@ RSpec.describe 'ProjectCiCdSettingsUpdate', feature_category: :continuous_integr
expect(project.ci_outbound_job_token_scope_enabled).to eq(false)
end
+ context 'when job_token_scope_enabled: true' do
+ let(:variables) do
+ {
+ full_path: project.full_path,
+ keep_latest_artifact: false,
+ job_token_scope_enabled: true,
+ inbound_job_token_scope_enabled: false,
+ opt_in_jwt: true
+ }
+ end
+
+ it 'prevents the update', :aggregate_failures do
+ project.update!(ci_outbound_job_token_scope_enabled: false)
+ post_graphql_mutation(mutation, current_user: user)
+
+ project.reload
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(graphql_errors).to(
+ include(
+ hash_including(
+ 'message' => 'job_token_scope_enabled can only be set to false'
+ )
+ )
+ )
+ expect(project.ci_outbound_job_token_scope_enabled).to eq(false)
+ end
+ end
+
+ context 'when FF frozen_outbound_job_token_scopes is disabled' do
+ before do
+ stub_feature_flags(frozen_outbound_job_token_scopes: false)
+ end
+
+ it 'allows setting job_token_scope_enabled to true' do
+ project.update!(ci_outbound_job_token_scope_enabled: true)
+ post_graphql_mutation(mutation, current_user: user)
+
+ project.reload
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(project.ci_outbound_job_token_scope_enabled).to eq(false)
+ end
+ end
+
it 'does not update job_token_scope_enabled if not specified' do
variables.except!(:job_token_scope_enabled)
diff --git a/spec/requests/api/internal/pages_spec.rb b/spec/requests/api/internal/pages_spec.rb
index a816b3870a1..1006319eabf 100644
--- a/spec/requests/api/internal/pages_spec.rb
+++ b/spec/requests/api/internal/pages_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe API::Internal::Pages, feature_category: :pages do
- let_it_be(:group) { create(:group, name: 'mygroup') }
- let_it_be_with_reload(:project) { create(:project, name: 'myproject', group: group) }
+ let_it_be(:group) { create(:group) }
+ let_it_be_with_reload(:project) { create(:project, group: group) }
let(:auth_header) do
{
@@ -228,7 +228,7 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
end
it 'responds with 204 No Content' do
- get api('/internal/pages'), headers: auth_header, params: { host: 'mygroup.gitlab-pages.io' }
+ get api('/internal/pages'), headers: auth_header, params: { host: "#{group.path}.gitlab-pages.io" }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('internal/pages/virtual_domain')
@@ -243,7 +243,7 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
context 'with a regular project' do
it 'responds with the correct domain configuration' do
- get api('/internal/pages'), headers: auth_header, params: { host: 'mygroup.gitlab-pages.io' }
+ get api('/internal/pages'), headers: auth_header, params: { host: "#{group.path}.gitlab-pages.io" }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('internal/pages/virtual_domain')
@@ -255,7 +255,7 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
'project_id' => project.id,
'access_control' => false,
'https_only' => false,
- 'prefix' => '/myproject/',
+ 'prefix' => "/#{project.path}/",
'source' => {
'type' => 'zip',
'path' => deployment.file.url(expire_at: 1.day.from_now),
@@ -274,7 +274,7 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
it 'avoids N+1 queries' do
control = ActiveRecord::QueryRecorder.new do
- get api('/internal/pages'), headers: auth_header, params: { host: 'mygroup.gitlab-pages.io' }
+ get api('/internal/pages'), headers: auth_header, params: { host: "#{group.path}.gitlab-pages.io" }
end
3.times do
@@ -282,17 +282,17 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
project.mark_pages_as_deployed
end
- expect { get api('/internal/pages'), headers: auth_header, params: { host: 'mygroup.gitlab-pages.io' } }
+ expect { get api('/internal/pages'), headers: auth_header, params: { host: "#{group.path}.gitlab-pages.io" } }
.not_to exceed_query_limit(control)
end
context 'with a group root project' do
before do
- project.update!(path: 'mygroup.gitlab-pages.io')
+ project.update!(path: "#{group.path}.gitlab-pages.io")
end
it 'responds with the correct domain configuration' do
- get api('/internal/pages'), headers: auth_header, params: { host: 'mygroup.gitlab-pages.io' }
+ get api('/internal/pages'), headers: auth_header, params: { host: "#{group.path}.gitlab-pages.io" }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('internal/pages/virtual_domain')
diff --git a/spec/requests/api/project_job_token_scope_spec.rb b/spec/requests/api/project_job_token_scope_spec.rb
new file mode 100644
index 00000000000..df210a00012
--- /dev/null
+++ b/spec/requests/api/project_job_token_scope_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::ProjectJobTokenScope, feature_category: :secrets_management do
+ describe 'GET /projects/:id/job_token_scope' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { create(:user) }
+
+ let(:get_job_token_scope_path) { "/projects/#{project.id}/job_token_scope" }
+
+ subject { get api(get_job_token_scope_path, user) }
+
+ context 'when unauthenticated user (missing user)' do
+ context 'for public project' do
+ it 'does not return ci cd settings of job token' do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+
+ get api(get_job_token_scope_path)
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+ end
+
+ context 'when authenticated user as maintainer' do
+ before_all { project.add_maintainer(user) }
+
+ it 'returns ci cd settings for job token scope' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to include(
+ "inbound_enabled" => true,
+ "outbound_enabled" => false
+ )
+ end
+
+ it 'returns the correct ci cd settings for job token scope after change' do
+ project.update!(ci_inbound_job_token_scope_enabled: false)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to include(
+ "inbound_enabled" => false,
+ "outbound_enabled" => false
+ )
+ end
+
+ it 'returns unauthorized and blank response when invalid auth credentials are given' do
+ invalid_personal_access_token = build(:personal_access_token, user: user)
+
+ get api(get_job_token_scope_path, user, personal_access_token: invalid_personal_access_token)
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(json_response).not_to include("inbound_enabled", "outbound_enabled")
+ end
+ end
+
+ context 'when authenticated user as developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'returns forbidden and no ci cd settings for public project' do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response).not_to include("inbound_enabled", "outbound_enabled")
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 49bfdf053ef..a47052f2d0a 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -63,8 +63,6 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
create(:project,
:private,
:repository,
- name: 'second_project',
- path: 'second_project',
creator_id: user.id,
namespace: user.namespace,
merge_requests_enabled: false,
@@ -82,8 +80,6 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
let_it_be(:project4, reload: true) do
create(:project,
- name: 'third_project',
- path: 'third_project',
creator_id: user4.id,
namespace: user4.namespace)
end
@@ -190,7 +186,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
context 'when unauthenticated' do
it_behaves_like 'projects response' do
- let(:filter) { { search: project.name } }
+ let(:filter) { { search: project.path } }
let(:current_user) { user }
let(:projects) { [project] }
end
@@ -545,7 +541,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
context 'and using search' do
it_behaves_like 'projects response' do
- let(:filter) { { search: project.name } }
+ let(:filter) { { search: project.path } }
let(:current_user) { user }
let(:projects) { [project] }
end
@@ -966,7 +962,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
expect(json_response.length).to eq(1)
project_names = json_response.map { |proj| proj['name'] }
- expect(project_names).to contain_exactly('Test Public Project')
+ expect(project_names).to contain_exactly(project_4.name)
end
end
end
@@ -1470,11 +1466,11 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
end
it 'creates a new project initialized with a README.md' do
- project = attributes_for(:project, initialize_with_readme: 1, name: 'somewhere')
+ project = attributes_for(:project, initialize_with_readme: 1)
post api(path, user), params: project
- expect(json_response['readme_url']).to eql("#{Gitlab.config.gitlab.url}/#{json_response['namespace']['full_path']}/somewhere/-/blob/master/README.md")
+ expect(json_response['readme_url']).to eql("#{Gitlab.config.gitlab.url}/#{json_response['namespace']['full_path']}/#{json_response['path']}/-/blob/master/README.md")
end
it 'sets tag list to a project (deprecated)' do
@@ -1660,7 +1656,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
end
describe 'GET /users/:user_id/projects/' do
- let!(:public_project) { create(:project, :public, name: 'public_project', creator_id: user4.id, namespace: user4.namespace) }
+ let_it_be(:public_project) { create(:project, :public, creator_id: user4.id, namespace: user4.namespace) }
it 'returns error when user not found' do
get api("/users/#{non_existing_record_id}/projects/")
@@ -1697,7 +1693,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
end
context 'and using id_after' do
- let!(:another_public_project) { create(:project, :public, name: 'another_public_project', creator_id: user4.id, namespace: user4.namespace) }
+ let_it_be(:another_public_project) { create(:project, :public, creator_id: user4.id, namespace: user4.namespace) }
it 'only returns projects with id_after filter given' do
get api("/users/#{user4.id}/projects?id_after=#{public_project.id}", user)
@@ -1719,7 +1715,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
end
context 'and using id_before' do
- let!(:another_public_project) { create(:project, :public, name: 'another_public_project', creator_id: user4.id, namespace: user4.namespace) }
+ let_it_be(:another_public_project) { create(:project, :public, creator_id: user4.id, namespace: user4.namespace) }
it 'only returns projects with id_before filter given' do
get api("/users/#{user4.id}/projects?id_before=#{another_public_project.id}", user)
@@ -1741,7 +1737,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :projects d
end
context 'and using both id_before and id_after' do
- let!(:more_projects) { create_list(:project, 5, :public, creator_id: user4.id, namespace: user4.namespace) }
+ let_it_be(:more_projects) { create_list(:project, 5, :public, creator_id: user4.id, namespace: user4.namespace) }
it 'only returns projects with id matching the range' do
get api("/users/#{user4.id}/projects?id_after=#{more_projects.first.id}&id_before=#{more_projects.last.id}", user)
diff --git a/spec/requests/api/release/links_spec.rb b/spec/requests/api/release/links_spec.rb
index 4b388304621..b8c10de2302 100644
--- a/spec/requests/api/release/links_spec.rb
+++ b/spec/requests/api/release/links_spec.rb
@@ -174,7 +174,7 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
specify do
get api("/projects/#{project.id}/releases/v0.1/assets/links/#{link.id}", maintainer)
- expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.namespace.path}/#{project.name}/-/releases/#{release.tag}/downloads/bin/bigfile.exe")
+ expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.full_path}/-/releases/#{release.tag}/downloads/bin/bigfile.exe")
end
end
@@ -391,7 +391,7 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
put api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", maintainer),
params: params.merge(direct_asset_path: '/binaries/awesome-app.msi')
- expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.namespace.path}/#{project.name}/-/releases/#{release.tag}/downloads/binaries/awesome-app.msi")
+ expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.full_path}/-/releases/#{release.tag}/downloads/binaries/awesome-app.msi")
end
end
diff --git a/spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb b/spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb
index dc87cc872e3..e6bdb2a3fc6 100644
--- a/spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb
+++ b/spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb
@@ -4,10 +4,10 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService, '#execute', :yaml_processor_feature_flag_corectness,
feature_category: :continuous_integration do
- let_it_be(:group) { create(:group, name: 'my-organization') }
+ let_it_be(:group) { create(:group) }
- let(:upstream_project) { create(:project, :repository, name: 'upstream', group: group) }
- let(:downstream_project) { create(:project, :repository, name: 'downstream', group: group) }
+ let(:upstream_project) { create(:project, :repository, group: group) }
+ let(:downstream_project) { create(:project, :repository, group: group) }
let(:user) { create(:user) }
let(:service) do
@@ -28,7 +28,7 @@ RSpec.describe Ci::CreatePipelineService, '#execute', :yaml_processor_feature_fl
stage: test
resource_group: iOS
trigger:
- project: my-organization/downstream
+ project: #{downstream_project.full_path}
strategy: depend
YAML
end
diff --git a/spec/services/ci/job_token_scope/add_project_service_spec.rb b/spec/services/ci/job_token_scope/add_project_service_spec.rb
index e6674ee384f..dc7ad81afef 100644
--- a/spec/services/ci/job_token_scope/add_project_service_spec.rb
+++ b/spec/services/ci/job_token_scope/add_project_service_spec.rb
@@ -37,8 +37,8 @@ RSpec.describe Ci::JobTokenScope::AddProjectService, feature_category: :continuo
it_behaves_like 'adds project'
- it 'creates an outbound link by default' do
- expect(resulting_direction).to eq('outbound')
+ it 'creates an inbound link by default' do
+ expect(resulting_direction).to eq('inbound')
end
context 'when direction is specified' do
diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
index 7e61d690ddd..48941792c4b 100644
--- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
+++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute',
let(:project) { cluster.project }
let(:environment) { create(:environment, project: project) }
let(:cluster_project) { cluster.cluster_project }
- let(:namespace) { "#{project.name}-#{project.id}-#{environment.slug}" }
+ let(:namespace) { "#{project.path}-#{project.id}-#{environment.slug}" }
subject do
described_class.new(
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index 10399bed655..27da948079e 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -458,7 +458,7 @@ RSpec.describe Groups::TransferService, :sidekiq_inline, feature_category: :subg
it 'updates projects path' do
new_parent_path = new_parent_group.path
group.projects.each do |project|
- expect(project.full_path).to eq("#{new_parent_path}/#{group.path}/#{project.name}")
+ expect(project.full_path).to eq("#{new_parent_path}/#{group.path}/#{project.path}")
end
end
@@ -525,7 +525,7 @@ RSpec.describe Groups::TransferService, :sidekiq_inline, feature_category: :subg
it 'updates projects path' do
new_parent_path = new_parent_group.path
group.projects.each do |project|
- expect(project.full_path).to eq("#{new_parent_path}/#{group.path}/#{project.name}")
+ expect(project.full_path).to eq("#{new_parent_path}/#{group.path}/#{project.path}")
end
end
@@ -576,7 +576,7 @@ RSpec.describe Groups::TransferService, :sidekiq_inline, feature_category: :subg
it 'updates projects path' do
new_parent_path = "#{new_parent_group.path}/#{group.path}"
subgroup1.projects.each do |project|
- project_full_path = "#{new_parent_path}/#{project.namespace.path}/#{project.name}"
+ project_full_path = "#{new_parent_path}/#{project.namespace.path}/#{project.path}"
expect(project.full_path).to eq(project_full_path)
end
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 2aba2303dd1..4ba72b5870d 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -150,12 +150,11 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management
context 'project already exists' do
it "fails due to validation, not transaction failure" do
- @existing_project = create(:project, :repository, creator_id: @to_user.id, name: @from_project.name, namespace: @to_namespace)
+ @existing_project = create(:project, :repository, creator_id: @to_user.id, path: @from_project.path, namespace: @to_namespace)
@to_project = fork_project(@from_project, @to_user, namespace: @to_namespace, using_service: true)
expect(@existing_project).to be_persisted
expect(@to_project).not_to be_persisted
- expect(@to_project.errors[:name]).to eq(['has already been taken'])
expect(@to_project.errors[:path]).to eq(['has already been taken'])
end
end
@@ -301,10 +300,9 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management
context 'project already exists in group' do
it 'fails due to validation, not transaction failure' do
- existing_project = create(:project, :repository, name: @project.name, namespace: @group)
+ existing_project = create(:project, :repository, path: @project.path, namespace: @group)
to_project = fork_project(@project, @group_owner, @opts)
expect(existing_project.persisted?).to be_truthy
- expect(to_project.errors[:name]).to eq(['has already been taken'])
expect(to_project.errors[:path]).to eq(['has already been taken'])
end
end
diff --git a/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb b/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb
index 22b401bc841..83bf622af67 100644
--- a/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb
+++ b/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb
@@ -8,7 +8,7 @@ RSpec.shared_context 'with GLFM example snapshot fixtures' do
# NOTE: We hardcode the IDs on all fixtures to prevent variability in the
# rendered HTML/Prosemirror JSON, and to minimize the need for normalization:
# https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#normalization
- create(:project, :repository, creator: user, group: group, name: 'glfm_project', id: 77777)
+ create(:project, :repository, creator: user, group: group, path: 'glfm_project', id: 77777)
end
let_it_be(:project_snippet) { create(:project_snippet, title: 'glfm_project_snippet', id: 88888, project: project) }
diff --git a/spec/support/shared_examples/mailers/notify_shared_examples.rb b/spec/support/shared_examples/mailers/notify_shared_examples.rb
index 4d039eccbf7..cf1ab7697ab 100644
--- a/spec/support/shared_examples/mailers/notify_shared_examples.rb
+++ b/spec/support/shared_examples/mailers/notify_shared_examples.rb
@@ -59,7 +59,7 @@ end
RSpec.shared_examples 'an email with X-GitLab headers containing project details' do
it 'has X-GitLab-Project headers' do
aggregate_failures do
- full_path_as_domain = "#{project.name}.#{project.namespace.path}"
+ full_path_as_domain = "#{project.path}.#{project.namespace.path}"
is_expected.to have_header('X-GitLab-Project', /#{project.name}/)
is_expected.to have_header('X-GitLab-Project-Id', /#{project.id}/)
is_expected.to have_header('X-GitLab-Project-Path', /#{project.full_path}/)
diff --git a/spec/support/shared_examples/requests/user_activity_shared_examples.rb b/spec/support/shared_examples/requests/user_activity_shared_examples.rb
index 37da1ce5c63..9c0165f7150 100644
--- a/spec/support/shared_examples/requests/user_activity_shared_examples.rb
+++ b/spec/support/shared_examples/requests/user_activity_shared_examples.rb
@@ -5,7 +5,7 @@ RSpec.shared_examples 'updating of user activity' do |paths_to_visit|
before do
group = create(:group, name: 'group')
- project = create(:project, :public, namespace: group, name: 'project')
+ project = create(:project, :public, namespace: group, path: 'project')
create(:issue, project: project, iid: 10)
create(:merge_request, source_project: project, iid: 15)
diff --git a/spec/uploaders/file_uploader_spec.rb b/spec/uploaders/file_uploader_spec.rb
index 76519545e24..3340725dd6d 100644
--- a/spec/uploaders/file_uploader_spec.rb
+++ b/spec/uploaders/file_uploader_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe FileUploader do
- let(:group) { create(:group, name: 'awesome') }
- let(:project) { create(:project, :legacy_storage, namespace: group, name: 'project') }
+ let(:group) { create(:group, path: 'awesome') }
+ let(:project) { create(:project, :legacy_storage, namespace: group, path: 'project') }
let(:uploader) { described_class.new(project, :avatar) }
let(:upload) { double(model: project, path: "#{secret}/foo.jpg") }
let(:secret) { "55dc16aa0edd05693fd98b5051e83321" } # this would be nicer as SecureRandom.hex, but the shared_examples breaks
@@ -23,7 +23,7 @@ RSpec.describe FileUploader do
context 'uses hashed storage' do
context 'when rolled out attachments' do
- let(:project) { build_stubbed(:project, namespace: group, name: 'project') }
+ let(:project) { build_stubbed(:project, namespace: group, path: 'project') }
include_examples 'builds correct paths',
store_dir: %r{@hashed/\h{2}/\h{2}/\h+},
@@ -31,7 +31,7 @@ RSpec.describe FileUploader do
end
context 'when only repositories are rolled out' do
- let(:project) { build_stubbed(:project, namespace: group, name: 'project', storage_version: Project::HASHED_STORAGE_FEATURES[:repository]) }
+ let(:project) { build_stubbed(:project, namespace: group, path: 'project', storage_version: Project::HASHED_STORAGE_FEATURES[:repository]) }
it_behaves_like 'builds correct legacy storage paths'
end