diff --git a/config/feature_flags/development/usage_data_i_testing_metrics_report_artifact_uploaders.yml b/config/feature_flags/development/usage_data_i_testing_metrics_report_artifact_uploaders.yml deleted file mode 100644 index 968ab3e63f1..00000000000 --- a/config/feature_flags/development/usage_data_i_testing_metrics_report_artifact_uploaders.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: usage_data_i_testing_metrics_report_artifact_uploaders -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51670 -rollout_issue_url: -milestone: '13.9' -type: development -group: group::testing -default_enabled: true diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md index cbe7f7de09b..bf5233f2dcf 100644 --- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md +++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md @@ -26,7 +26,7 @@ As GitLab changes, changes to the code are inevitable, and so some scripts may not work as they once used to. These are not kept up-to-date as these scripts/commands were added as they were found/needed. As mentioned above, we recommend running these scripts under the supervision of a -Support Engineer, who can also verify that they will continue to work as they +Support Engineer, who can also verify that they continue to work as they should and, if needed, update the script for the latest version of GitLab. ## Find specific methods for an object @@ -185,7 +185,7 @@ Project.update_all(visibility_level: 0) ```ruby # -# This section will list all the projects which are pending deletion +# This section lists all the projects which are pending deletion # projects = Project.where(pending_delete: true) projects.each do |p| @@ -195,7 +195,7 @@ projects.each do |p| end # -# Assign a user (the root user will do) +# Assign a user (the root user does) # user = User.find_by_username('root') @@ -255,7 +255,7 @@ namespace = Namespace.find_by_full_path("") ### For Removing webhooks that is getting timeout due to large webhook logs ```ruby -# ID will be the webhook_id +# ID is the webhook_id hook=WebHook.find(ID) WebHooks::DestroyService.new(current_user).execute(hook) @@ -397,7 +397,7 @@ projects = Project.find_by_sql("SELECT * FROM projects WHERE name LIKE '%ject'") ### Recreate WARNING: -This is a destructive operation, the Wiki will be empty. +This is a destructive operation, the Wiki becomes empty. A Projects Wiki can be recreated by this command: @@ -474,13 +474,13 @@ Projects::ImportExport::ExportService.new(project, user).execute If the project you wish to export is available at `https://gitlab.example.com/baltig/pipeline-templates`, the value to use for `PROJECT_PATH` would be `baltig/pipeline-templates`. -If this all runs successfully, you will see output like the following before being returned to the Rails console prompt: +If this all runs successfully, you see an output like the following before being returned to the Rails console prompt: ```ruby => nil ``` -The exported project will be located within a `.tar.gz` file in `/var/opt/gitlab/gitlab-rails/uploads/-/system/import_export_upload/export_file/`. +The exported project is located within a `.tar.gz` file in `/var/opt/gitlab/gitlab-rails/uploads/-/system/import_export_upload/export_file/`. ## Repository @@ -490,10 +490,10 @@ If it seems that a commit has gone "missing", search the sequence of pushes to a [This StackOverflow article](https://stackoverflow.com/questions/13468027/the-mystery-of-the-missing-commit-across-merges) describes how you can end up in this state without a force push. -If you look at the output from the sample code below for the target branch, you will +If you look at the output from the sample code below for the target branch, you see a discontinuity in the from/to commits as you step through the output. Each new push should be "from" the "to" SHA of the previous push. When this discontinuity happens, -you will see two pushes with the same "from" SHA: +you see two pushes with the same "from" SHA: ```ruby p = Project.find_with_namespace('u/p') @@ -556,7 +556,7 @@ end ```ruby u = User.new(username: 'test_user', email: 'test@example.com', name: 'Test User', password: 'password', password_confirmation: 'password') -u.skip_confirmation! # Use it only if you wish user to be automatically confirmed. If skipped, user will recieve confirmation e-mail +u.skip_confirmation! # Use it only if you wish user to be automatically confirmed. If skipped, user receives confirmation e-mail u.save! ``` @@ -610,7 +610,7 @@ identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users] ```ruby users = User.where('id NOT IN (select distinct(user_id) from project_authorizations)') -# How many users will be removed? +# How many users are removed? users.count # If that count looks sane: @@ -1071,7 +1071,7 @@ encrypted credentials to allow manual reentry: If `User OTP Secret Bad count:` is detected. For each user listed disable/enable two-factor authentication. -The following script will search in some of the tables for encrypted tokens that are +The following script searches in some of the tables for encrypted tokens that are causing decryption errors, and update or reset as needed: ```shell @@ -1133,7 +1133,7 @@ Geo::ProjectRegistry.sync_failed('repository') ### Resync repositories -#### Queue up all repositories for resync. Sidekiq will handle each sync +#### Queue up all repositories for resync. Sidekiq handles each sync ```ruby Geo::ProjectRegistry.update_all(resync_repository: true, resync_wiki: true) @@ -1180,10 +1180,10 @@ registry.replicator.send(:download) #### Verify package files on the secondary manually -This will iterate over all package files on the secondary, looking at the +This iterates over all package files on the secondary, looking at the `verification_checksum` stored in the database (which came from the primary) and then calculate this value on the secondary to check if they match. This -won't change anything in the UI: +does not change anything in the UI: ```ruby # Run on secondary @@ -1245,7 +1245,7 @@ Gitlab::UsageData.to_json ### Generate a fresh new Service Ping -This will also refresh the cached Service Ping displayed in the admin area +This also refreshes the cached Service Ping displayed in the Admin Area ```ruby Gitlab::UsageData.to_json(force_refresh: true) @@ -1299,7 +1299,7 @@ Open the rails console (`gitlab rails c`) and run the following command to see a ApplicationSetting.last.attributes ``` -Among other attributes, in the output you will notice that all the settings available in the [Elasticsearch Integration page](../../integration/elasticsearch.md), like: `elasticsearch_indexing`, `elasticsearch_url`, `elasticsearch_replicas`, `elasticsearch_pause_indexing`, and so on. +Among other attributes, the output contains all the settings available in the [Elasticsearch Integration page](../../integration/elasticsearch.md), such as `elasticsearch_indexing`, `elasticsearch_url`, `elasticsearch_replicas`, and `elasticsearch_pause_indexing`. #### Setting attributes diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md index b4e32066ba8..82fd37eacaf 100644 --- a/doc/development/cicd/index.md +++ b/doc/development/cicd/index.md @@ -157,7 +157,7 @@ On top of that, we have the following types of jobs: - `Ci::Build` ... The job to be executed by runners. - `Ci::Bridge` ... The job to trigger a downstream pipeline. -- `GenericCommitStatus` ... The job to be executed in an external CI/CD system e.g. Jenkins. +- `GenericCommitStatus` ... The job to be executed in an external CI/CD system, for example Jenkins. When you use the "Job" terminology in codebase, readers would assume that the class/object is any type of above. diff --git a/doc/development/code_review.md b/doc/development/code_review.md index 12cc63ef56d..8fa7d1be04c 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -156,7 +156,7 @@ See the [test engineering process](https://about.gitlab.com/handbook/engineering 1. I have confirmed that this change is [backwards compatible across updates](multi_version_compatibility.md), or I have decided that this does not apply. 1. I have properly separated EE content from FOSS, or this MR is FOSS only. - [Where should EE code go?](ee_features.md#separation-of-ee-code) -1. If I am introducing a new expectation for existing data, I have confirmed that existing data meets this expectation or I have made this expectation optional rather than required. +1. I have considered that existing data may be surprisingly varied. For example, a new model validation can break existing records. Consider making validation on existing data optional rather than required if you haven't confirmed that existing data will pass validation. ##### Performance, reliability, and availability diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md index 29f6eb57160..6ab51067b0d 100644 --- a/doc/development/contributing/issue_workflow.md +++ b/doc/development/contributing/issue_workflow.md @@ -151,7 +151,7 @@ From the handbook's page: > Categories are high-level capabilities that may be a standalone product at -another company. e.g. Portfolio Management. +another company, such as Portfolio Management, for example. It's highly recommended to add a category label, as it's used by our triage automation to @@ -182,7 +182,7 @@ From the handbook's [Product stages, groups, and categories](https://about.gitlab.com/handbook/product/categories/#hierarchy) page: -> Features: Small, discrete functionalities. e.g. Issue weights. Some common +> Features: Small, discrete functionalities, for example Issue weights. Some common features are listed within parentheses to facilitate finding responsible PMs by keyword. It's highly recommended to add a feature label if no category label applies, as diff --git a/doc/development/distributed_tracing.md b/doc/development/distributed_tracing.md index f8184a562ec..1e85abf585c 100644 --- a/doc/development/distributed_tracing.md +++ b/doc/development/distributed_tracing.md @@ -57,7 +57,7 @@ on non-Go GitLab subsystems. ## Enabling distributed tracing GitLab uses the `GITLAB_TRACING` environment variable to configure distributed tracing. The same -configuration is used for all components (e.g., Workhorse, Rails, etc). +configuration is used for all components (for example, Workhorse, Rails, etc). When `GITLAB_TRACING` is not set, the application isn't instrumented, meaning that there is no overhead at all. diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md index cecbb362cb9..3799c99bed8 100644 --- a/doc/subscriptions/gitlab_com/index.md +++ b/doc/subscriptions/gitlab_com/index.md @@ -389,7 +389,8 @@ Be aware that: be charged for less than one year because your subscription was previously created with the extra CI minutes. - After the extra CI minutes have been assigned to a Group, they can't be transferred - to a different Group. + to a different Group by themselves, but they will transfer along with a subscription when + changing the linked namespace for the subscription. - If you have used more minutes than your default quota, these minutes will be deducted from your Additional Minutes quota immediately after your purchase of additional minutes. diff --git a/doc/user/admin_area/settings/sign_in_restrictions.md b/doc/user/admin_area/settings/sign_in_restrictions.md index 29cf0bb9d23..8cee63b0ac2 100644 --- a/doc/user/admin_area/settings/sign_in_restrictions.md +++ b/doc/user/admin_area/settings/sign_in_restrictions.md @@ -106,7 +106,7 @@ see [Email notification for unknown sign-ins](../../profile/unknown_sign_in_noti All users that are not logged in are redirected to the page represented by the configured **Home page URL** if value is not empty. -All users are redirected to the page represented by the configured **After sign out path** +All users are redirected to the page represented by the configured **After sign-out path** after sign out if value is not empty. In the **Sign-in restrictions** section, scroll to the **Sign-in text** field. You can add a diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md index 1db2165cd5d..d27fbe3508f 100644 --- a/doc/user/packages/container_registry/index.md +++ b/doc/user/packages/container_registry/index.md @@ -913,8 +913,8 @@ these steps: ### Troubleshoot as a GitLab server admin -Troubleshooting the GitLab Container Registry, most of the times, requires -administrator access to the GitLab server. +Troubleshooting the GitLab Container Registry, most of the times, requires +you to log in to GitLab server with the Administrator role. [Read how to troubleshoot the Container Registry](../../../administration/packages/container_registry.md#troubleshooting). diff --git a/doc/user/packages/debian_repository/index.md b/doc/user/packages/debian_repository/index.md index 29641380753..c8939fcd00d 100644 --- a/doc/user/packages/debian_repository/index.md +++ b/doc/user/packages/debian_repository/index.md @@ -138,7 +138,7 @@ To install a package: 1. Configure the repository: - If you are using a private project, add your [credentials](#authenticate-to-the-package-registry) to your apt config: + If you are using a private project, add your [credentials](#authenticate-to-the-package-registry) to your apt configuration: ```shell echo 'machine gitlab.example.com login password ' \ diff --git a/doc/user/packages/helm_repository/index.md b/doc/user/packages/helm_repository/index.md index 2d984d76b97..d6ac44268c6 100644 --- a/doc/user/packages/helm_repository/index.md +++ b/doc/user/packages/helm_repository/index.md @@ -105,7 +105,7 @@ helm install my-release project-1/mychart - ``: the project ID (like `42`). - ``: the name of the channel (like `stable`). -If the repo has previously been added, you may need to run: +If the repository has previously been added, you may need to run: ```shell helm repo update diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md index 65e1eafa477..887eb546148 100644 --- a/doc/user/project/import/index.md +++ b/doc/user/project/import/index.md @@ -47,7 +47,7 @@ information, see [the import notes](../settings/import_export.md#important-notes NOTE: When migrating to GitLab.com, you must create users manually unless [SCIM](../../../user/group/saml_sso/scim_setup.md) will be used. Creating users with the API is limited to self-managed instances as it requires -administrator access. +the Administrator role. To migrate all data from self-managed to GitLab.com, you can leverage the [API](../../../api/index.md). Migrate the assets in this order: diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress.md b/doc/user/project/integrations/prometheus_library/nginx_ingress.md index d1fe58390fe..6478011b730 100644 --- a/doc/user/project/integrations/prometheus_library/nginx_ingress.md +++ b/doc/user/project/integrations/prometheus_library/nginx_ingress.md @@ -38,6 +38,8 @@ Managing these settings depends on how NGINX Ingress has been deployed. If you h ## Specifying the Environment label -In order to isolate and only display relevant metrics for a given environment, GitLab needs a method to detect which labels are associated. To do this, GitLab searches for metrics with appropriate labels. In this case, the `ingress` label must ``. +To isolate and display only relevant metrics for a given environment, GitLab needs a method to +detect which labels are associated. To do this, GitLab searches for metrics with appropriate labels. +In this case, the `ingress` label must include the value ``. If you have used [Auto Deploy](../../../../topics/autodevops/stages.md#auto-deploy) to deploy your app, this format is used automatically and metrics are detected with no action on your part. diff --git a/doc/user/project/issues/due_dates.md b/doc/user/project/issues/due_dates.md index 5b8dd617ab9..94a5fdc3f0f 100644 --- a/doc/user/project/issues/due_dates.md +++ b/doc/user/project/issues/due_dates.md @@ -15,7 +15,7 @@ the issue can view the due date. When creating an issue, select the **Due date** field to make a calendar appear for choosing the date. To remove the date, select the date -text and delete it. The date is related to the server's timezone, not the timezone of +text and delete it. The date is related to the server's time zone, not the time zone of the user setting the due date. ![Create a due date](img/due_dates_create.png) @@ -45,7 +45,7 @@ Due dates also appear in your [to-do list](../../todos.md). The day before an open issue is due, an email is sent to all participants of the issue. Like the due date, the "day before the due date" is determined by the -server's timezone. +server's time zone. Issues with due dates can also be exported as an iCalendar feed. The URL of the feed can be added to calendar applications. The feed is accessible by selecting diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index 385a4fafa7d..9bd853c8775 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -87,7 +87,7 @@ GitLab Pages website. You can either use the GitLab [default domain for GitLab Pages websites](getting_started_part_one.md#gitlab-pages-default-domain-names), `*.gitlab.io`, or your own domain (`example.com`). In that case, you -need administrator access to your domain's registrar (or control panel) to set it up with Pages. +must have the Administrator role in your domain's registrar (or control panel) to set it up with Pages. The following diagrams show the workflows you might follow to get started with Pages. diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index 49b5ec2ca60..9e4d621dbc6 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -218,7 +218,7 @@ To set a deploy freeze window in the UI, complete these steps: 1. Scroll to **Deploy freezes**. 1. Click **Expand** to see the deploy freeze table. 1. Click **Add deploy freeze** to open the deploy freeze modal. -1. Enter the start time, end time, and timezone of the desired deploy freeze period. +1. Enter the start time, end time, and time zone of the desired deploy freeze period. 1. Click **Add deploy freeze** in the modal. 1. After the deploy freeze is saved, you can edit it by selecting the edit button (**{pencil}**) and remove it by selecting the delete button (**{remove}**). ![Deploy freeze modal for setting a deploy freeze period](img/deploy_freeze_v14_3.png) diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 385ac40cf13..b2e2b013947 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -49,18 +49,23 @@ module Gitlab # It does not include the default public schema EXTRA_SCHEMAS = [DYNAMIC_PARTITIONS_SCHEMA, STATIC_PARTITIONS_SCHEMA].freeze - DATABASES = ActiveRecord::Base - .connection_handler - .connection_pools - .each_with_object({}) do |pool, hash| - hash[pool.db_config.name.to_sym] = Connection.new(pool.connection_klass) - end - .freeze - PRIMARY_DATABASE_NAME = ActiveRecord::Base.connection_db_config.name.to_sym + def self.database_base_models + @database_base_models ||= { + main: ::ApplicationRecord, + ci: ::Ci::CiDatabaseRecord.connection_class? ? ::Ci::CiDatabaseRecord : nil + }.compact.freeze + end + + def self.databases + @databases ||= database_base_models + .transform_values { |connection_class| Connection.new(connection_class) } + .freeze + end + def self.main - DATABASES[PRIMARY_DATABASE_NAME] + databases[PRIMARY_DATABASE_NAME] end # We configure the database connection pool size automatically based on the @@ -99,7 +104,7 @@ module Gitlab def self.check_postgres_version_and_print_warning return if Gitlab::Runtime.rails_runner? - DATABASES.each do |name, connection| + databases.each do |name, connection| next if connection.postgresql_minimum_supported_version? Kernel.warn ERB.new(Rainbow.new.wrap(<<~EOS).red).result @@ -111,7 +116,7 @@ module Gitlab  ███ ███  ██  ██ ██  ██ ██   ████ ██ ██   ████  ██████   ****************************************************************************** - You are using PostgreSQL <%= Gitlab::Database.main.version %> for the #{name} database, but PostgreSQL >= <%= Gitlab::Database::MINIMUM_POSTGRES_VERSION %> + You are using PostgreSQL #{connection.version} for the #{name} database, but PostgreSQL >= <%= Gitlab::Database::MINIMUM_POSTGRES_VERSION %> is required for this version of GitLab. <% if Rails.env.development? || Rails.env.test? %> If using gitlab-development-kit, please find the relevant steps here: diff --git a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb index 518a812b406..08198169688 100644 --- a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb +++ b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb @@ -31,7 +31,7 @@ module Gitlab def set_data_consistency_locations!(job) # Once we add support for multiple databases to our load balancer, we would use something like this: - # job['wal_locations'] = Gitlab::Database::DATABASES.transform_values do |connection| + # job['wal_locations'] = Gitlab::Database.databases.transform_values do |connection| # connection.load_balancer.primary_write_location # end # diff --git a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb index 15f8f0fb240..5e391c7228d 100644 --- a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb +++ b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb @@ -92,7 +92,7 @@ module Gitlab def all_databases_has_replica_caught_up?(wal_locations) wal_locations.all? do |_config_name, location| # Once we add support for multiple databases to our load balancer, we would use something like this: - # Gitlab::Database::DATABASES[config_name].load_balancer.select_up_to_date_host(location) + # Gitlab::Database.databases[config_name].load_balancer.select_up_to_date_host(location) load_balancer.select_up_to_date_host(location) end end @@ -101,7 +101,7 @@ module Gitlab # Once we add support for multiple databases to our load balancer, we would use something like this: # connection.load_balancer.primary_write_location # - # Gitlab::Database::DATABASES.values.each do |connection| + # Gitlab::Database.databases.values.each do |connection| # connection.load_balancer.release_host # end load_balancer.release_host diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb index aeb58d7c153..ff7f16d81ab 100644 --- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb +++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb @@ -155,7 +155,7 @@ module Gitlab end def pg_wal_lsn_diff(connection_name) - Gitlab::Database::DATABASES[connection_name].pg_wal_lsn_diff(job_wal_locations[connection_name], existing_wal_locations[connection_name]) + Gitlab::Database.databases[connection_name].pg_wal_lsn_diff(job_wal_locations[connection_name], existing_wal_locations[connection_name]) end def strategy diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index 261d3b37783..dc885819069 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -179,7 +179,6 @@ category: testing redis_slot: testing aggregation: weekly - feature_flag: usage_data_i_testing_metrics_report_artifact_uploaders - name: i_testing_summary_widget_total category: testing redis_slot: testing diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d11ad6ab9a9..4e13720ad84 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -31349,6 +31349,9 @@ msgstr "" msgid "Site profile not found for given parameters" msgstr "" +msgid "Sites" +msgstr "" + msgid "Size" msgstr "" diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb index 01898c6f256..cc1d402dca9 100644 --- a/spec/requests/api/issues/post_projects_issues_spec.rb +++ b/spec/requests/api/issues/post_projects_issues_spec.rb @@ -516,7 +516,7 @@ RSpec.describe API::Issues do end context 'when using the issue ID instead of iid' do - it 'returns 404 when trying to move an issue' do + it 'returns 404 when trying to move an issue', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/341520' do post api("/projects/#{project.id}/issues/#{issue.id}/move", user), params: { to_project_id: target_project.id } @@ -608,7 +608,7 @@ RSpec.describe API::Issues do end context 'when using the issue ID instead of iid' do - it 'returns 404' do + it 'returns 404', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/341520' do post api("/projects/#{project.id}/issues/#{issue.id}/clone", user), params: { to_project_id: valid_target_project.id } @@ -683,7 +683,7 @@ RSpec.describe API::Issues do expect(response).to have_gitlab_http_status(:not_found) end - it 'returns 404 if the issue ID is used instead of the iid' do + it 'returns 404 if the issue ID is used instead of the iid', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/341520' do post api("/projects/#{project.id}/issues/#{issue.id}/subscribe", user) expect(response).to have_gitlab_http_status(:not_found) @@ -716,7 +716,7 @@ RSpec.describe API::Issues do expect(response).to have_gitlab_http_status(:not_found) end - it 'returns 404 if using the issue ID instead of iid' do + it 'returns 404 if using the issue ID instead of iid', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/341520' do post api("/projects/#{project.id}/issues/#{issue.id}/unsubscribe", user) expect(response).to have_gitlab_http_status(:not_found)