From f70958a8932f70733e08ee1774edd28423bac59e Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sat, 24 Sep 2022 00:14:11 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../javascripts/blob/3d_viewer/index.js | 2 +- .../javascripts/blob/3d_viewer/mesh_object.js | 2 +- .../list/components/issues_list_app.vue | 4 +- .../javascripts/issues/list/constants.js | 4 ++ .../concerns/issuable_collections_action.rb | 5 +- app/controllers/projects/issues_controller.rb | 1 + app/graphql/graphql_triggers.rb | 4 ++ app/graphql/types/subscription_type.rb | 3 ++ .../concerns/integrations/has_web_hook.rb | 2 +- app/models/hooks/service_hook.rb | 2 +- app/models/issue.rb | 13 ++++-- app/services/boards/issues/list_service.rb | 2 +- app/services/issuable_base_service.rb | 8 +++- app/services/merge_requests/update_service.rb | 1 + ...broadcast_issuable_description_updated.yml | 8 ++++ config/initializers/0_log_deprecations.rb | 5 ++ config/initializers/7_redis.rb | 2 +- ...0831090454_cleanup_web_hooks_service_id.rb | 13 ++++++ db/schema_migrations/20220831090454 | 1 + db/structure.sql | 46 ------------------- .../cache/ci/project_pipeline_status.rb | 2 +- lib/gitlab/ci/trace.rb | 2 +- lib/gitlab/exclusive_lease.rb | 2 +- lib/gitlab/repository_set_cache.rb | 4 +- lib/gitlab/set_cache.rb | 4 +- lib/gitlab/sidekiq_daemon/monitor.rb | 2 +- locale/gitlab.pot | 3 -- spec/controllers/dashboard_controller_spec.rb | 31 +++++++++++-- .../projects/issues_controller_spec.rb | 16 ++++++- .../blob/3d_viewer/mesh_object_spec.js | 2 +- spec/graphql/graphql_triggers_spec.rb | 14 ++++++ spec/graphql/types/subscription_type_spec.rb | 1 + spec/initializers/0_log_deprecations_spec.rb | 12 +++++ spec/lib/gitlab/anonymous_session_spec.rb | 2 +- .../cache/ci/project_pipeline_status_spec.rb | 2 +- spec/lib/gitlab/ci/trace_spec.rb | 2 +- .../project/relation_factory_spec.rb | 18 ++++---- spec/lib/gitlab/sidekiq_status_spec.rb | 8 ++-- .../ci/build_trace_chunks/redis_spec.rb | 8 ++-- .../models/concerns/counter_attribute_spec.rb | 4 +- spec/services/issues/update_service_spec.rb | 26 +++++++++++ .../merge_requests/update_service_spec.rb | 26 +++++++++++ .../work_items/update_service_spec.rb | 32 +++++++++++++ .../counter_attribute_shared_examples.rb | 8 ++-- .../has_web_hook_shared_examples.rb | 2 +- 45 files changed, 258 insertions(+), 103 deletions(-) create mode 100644 config/feature_flags/development/broadcast_issuable_description_updated.yml create mode 100644 db/post_migrate/20220831090454_cleanup_web_hooks_service_id.rb create mode 100644 db/schema_migrations/20220831090454 diff --git a/app/assets/javascripts/blob/3d_viewer/index.js b/app/assets/javascripts/blob/3d_viewer/index.js index 2831c37838b..4fbc9044cf0 100644 --- a/app/assets/javascripts/blob/3d_viewer/index.js +++ b/app/assets/javascripts/blob/3d_viewer/index.js @@ -1,6 +1,6 @@ import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'; -import * as THREE from 'three/build/three.module'; +import * as THREE from 'three'; import MeshObject from './mesh_object'; export default class Renderer { diff --git a/app/assets/javascripts/blob/3d_viewer/mesh_object.js b/app/assets/javascripts/blob/3d_viewer/mesh_object.js index 5322dc00e86..6c816b2d07f 100644 --- a/app/assets/javascripts/blob/3d_viewer/mesh_object.js +++ b/app/assets/javascripts/blob/3d_viewer/mesh_object.js @@ -1,4 +1,4 @@ -import { Matrix4, MeshLambertMaterial, Mesh } from 'three/build/three.module'; +import { Matrix4, MeshLambertMaterial, Mesh } from 'three'; const defaultColor = 0xe24329; const materials = { diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue index 0b424d105b9..151ae3536a7 100644 --- a/app/assets/javascripts/issues/list/components/issues_list_app.vue +++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue @@ -247,8 +247,8 @@ export default { }, defaultWorkItemTypes() { return this.isWorkItemsEnabled - ? defaultWorkItemTypes.concat(WORK_ITEM_TYPE_ENUM_TASK) - : defaultWorkItemTypes; + ? defaultWorkItemTypes + : defaultWorkItemTypes.filter((type) => type !== WORK_ITEM_TYPE_ENUM_TASK); }, typeTokenOptions() { return this.isWorkItemsEnabled diff --git a/app/assets/javascripts/issues/list/constants.js b/app/assets/javascripts/issues/list/constants.js index 75aa3bfcdca..aac894cb490 100644 --- a/app/assets/javascripts/issues/list/constants.js +++ b/app/assets/javascripts/issues/list/constants.js @@ -12,6 +12,7 @@ import { WORK_ITEM_TYPE_ENUM_INCIDENT, WORK_ITEM_TYPE_ENUM_ISSUE, WORK_ITEM_TYPE_ENUM_TEST_CASE, + WORK_ITEM_TYPE_ENUM_TASK, } from '~/work_items/constants'; export const i18n = { @@ -151,10 +152,13 @@ export const TOKEN_TYPE_HEALTH = 'health_status'; export const TYPE_TOKEN_TASK_OPTION = { icon: 'task-done', title: 'task', value: 'task' }; +// This should be consistent with Issue::TYPES_FOR_LIST in the backend +// https://gitlab.com/gitlab-org/gitlab/-/blob/1379c2d7bffe2a8d809f23ac5ef9b4114f789c07/app/models/issue.rb#L48 export const defaultWorkItemTypes = [ WORK_ITEM_TYPE_ENUM_ISSUE, WORK_ITEM_TYPE_ENUM_INCIDENT, WORK_ITEM_TYPE_ENUM_TEST_CASE, + WORK_ITEM_TYPE_ENUM_TASK, ]; export const defaultTypeTokenOptions = [ diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb index 96cf6021ea9..e03d1de7bf9 100644 --- a/app/controllers/concerns/issuable_collections_action.rb +++ b/app/controllers/concerns/issuable_collections_action.rb @@ -59,9 +59,12 @@ module IssuableCollectionsAction end def finder_options + issue_types = Issue::TYPES_FOR_LIST + issue_types = issue_types.excluding('task') unless Feature.enabled?(:work_items) + super.merge( non_archived: true, - issue_types: Issue::TYPES_FOR_LIST + issue_types: issue_types ) end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 5168c9adb79..cfc931e121f 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -405,6 +405,7 @@ class Projects::IssuesController < Projects::ApplicationController options = super options[:issue_types] = Issue::TYPES_FOR_LIST + options[:issue_types] = options[:issue_types].excluding('task') unless project.work_items_feature_flag_enabled? if service_desk? options.reject! { |key| key == 'author_username' || key == 'author_id' } diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb index 8086d8c02a4..2d25a675a46 100644 --- a/app/graphql/graphql_triggers.rb +++ b/app/graphql/graphql_triggers.rb @@ -13,6 +13,10 @@ module GraphqlTriggers GitlabSchema.subscriptions.trigger('issuableTitleUpdated', { issuable_id: issuable.to_gid }, issuable) end + def self.issuable_description_updated(issuable) + GitlabSchema.subscriptions.trigger('issuableDescriptionUpdated', { issuable_id: issuable.to_gid }, issuable) + end + def self.issuable_labels_updated(issuable) GitlabSchema.subscriptions.trigger('issuableLabelsUpdated', { issuable_id: issuable.to_gid }, issuable) end diff --git a/app/graphql/types/subscription_type.rb b/app/graphql/types/subscription_type.rb index ef701bbfc10..a6fad4ad46a 100644 --- a/app/graphql/types/subscription_type.rb +++ b/app/graphql/types/subscription_type.rb @@ -13,6 +13,9 @@ module Types field :issuable_title_updated, subscription: Subscriptions::IssuableUpdated, null: true, description: 'Triggered when the title of an issuable is updated.' + field :issuable_description_updated, subscription: Subscriptions::IssuableUpdated, null: true, + description: 'Triggered when the description of an issuable is updated.' + field :issuable_labels_updated, subscription: Subscriptions::IssuableUpdated, null: true, description: 'Triggered when the labels of an issuable are updated.' diff --git a/app/models/concerns/integrations/has_web_hook.rb b/app/models/concerns/integrations/has_web_hook.rb index e6ca6cc7938..b5d69d1574d 100644 --- a/app/models/concerns/integrations/has_web_hook.rb +++ b/app/models/concerns/integrations/has_web_hook.rb @@ -6,7 +6,7 @@ module Integrations included do after_save :update_web_hook!, if: :activated? - has_one :service_hook, inverse_of: :integration, foreign_key: :service_id + has_one :service_hook, inverse_of: :integration, foreign_key: :integration_id end # Return the URL to be used for the webhook. diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb index 80e167b350b..27119d3a95a 100644 --- a/app/models/hooks/service_hook.rb +++ b/app/models/hooks/service_hook.rb @@ -4,7 +4,7 @@ class ServiceHook < WebHook include Presentable extend ::Gitlab::Utils::Override - belongs_to :integration, foreign_key: :service_id + belongs_to :integration validates :integration, presence: true def execute(data, hook_name = 'service_hook') diff --git a/app/models/issue.rb b/app/models/issue.rb index 153747c75df..353e12b6c5c 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -40,10 +40,15 @@ class Issue < ApplicationRecord SORTING_PREFERENCE_FIELD = :issues_sort - # Types of issues that should be displayed on lists across the app - # for example, project issues list, group issues list and issue boards. - # Some issue types, like test cases, should be hidden by default. - TYPES_FOR_LIST = %w(issue incident).freeze + # Types of issues that should be displayed on issue lists across the app + # for example, project issues list, group issues list, and issues dashboard. + # + # This should be kept consistent with the enums used for the GraphQL issue list query in + # https://gitlab.com/gitlab-org/gitlab/-/blob/1379c2d7bffe2a8d809f23ac5ef9b4114f789c07/app/assets/javascripts/issues/list/constants.js#L154-158 + TYPES_FOR_LIST = %w(issue incident test_case task).freeze + + # Types of issues that should be displayed on issue board lists + TYPES_FOR_BOARD_LIST = %w(issue incident).freeze belongs_to :project belongs_to :namespace, inverse_of: :issues diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 465025ef2e9..fcaa74555ca 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -50,7 +50,7 @@ module Boards end def set_issue_types - params[:issue_types] ||= Issue::TYPES_FOR_LIST + params[:issue_types] ||= Issue::TYPES_FOR_BOARD_LIST end def item_model diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 70ad97f8436..925a094e0f4 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -267,7 +267,13 @@ class IssuableBaseService < ::BaseProjectService end def after_update(issuable) - # To be overridden by subclasses + handle_description_updated(issuable) if Feature.enabled?(:broadcast_issuable_description_updated) + end + + def handle_description_updated(issuable) + return unless issuable.previous_changes.include?('description') + + GraphqlTriggers.issuable_description_updated(issuable) end def update(issuable) diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 6d518edc88f..98b120360cd 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -72,6 +72,7 @@ module MergeRequests end def after_update(issuable) + super issuable.cache_merge_request_closes_issues!(current_user) end diff --git a/config/feature_flags/development/broadcast_issuable_description_updated.yml b/config/feature_flags/development/broadcast_issuable_description_updated.yml new file mode 100644 index 00000000000..9525717da8d --- /dev/null +++ b/config/feature_flags/development/broadcast_issuable_description_updated.yml @@ -0,0 +1,8 @@ +--- +name: broadcast_issuable_description_updated +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98458 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/375183 +milestone: '15.5' +type: development +group: group::project management +default_enabled: false diff --git a/config/initializers/0_log_deprecations.rb b/config/initializers/0_log_deprecations.rb index b3ef391053e..5e6d18f0f60 100644 --- a/config/initializers/0_log_deprecations.rb +++ b/config/initializers/0_log_deprecations.rb @@ -26,6 +26,11 @@ if log_deprecations? Gitlab::DeprecationJsonLogger.info(message: warning.strip, source: 'ruby') # Returning :default means we continue emitting this to stderr as well. :default + end, + # This won't be needed when https://gitlab.com/gitlab-org/gitlab/-/issues/340602 is completed + /\A`Redis#exists\(key\)` will return an Integer in redis-rb 4\.3/ => lambda do |warning| + Gitlab::DeprecationJsonLogger.info(message: warning.strip, source: 'redis') + :default end } diff --git a/config/initializers/7_redis.rb b/config/initializers/7_redis.rb index 1e2786db413..fc6c29f9cd6 100644 --- a/config/initializers/7_redis.rb +++ b/config/initializers/7_redis.rb @@ -8,7 +8,7 @@ Redis.raise_deprecations = true unless Rails.env.production? # We cannot switch to the new behavior until we change all existing `redis.exists` calls to `redis.exists?`. # Some gems also need to be updated # https://gitlab.com/gitlab-org/gitlab/-/issues/340602 -Redis.instance_variable_set(:@exists_returns_integer, false) +Redis.instance_variable_set(:@exists_returns_integer, nil) Redis::Client.prepend(Gitlab::Instrumentation::RedisInterceptor) diff --git a/db/post_migrate/20220831090454_cleanup_web_hooks_service_id.rb b/db/post_migrate/20220831090454_cleanup_web_hooks_service_id.rb new file mode 100644 index 00000000000..7beb89038e5 --- /dev/null +++ b/db/post_migrate/20220831090454_cleanup_web_hooks_service_id.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CleanupWebHooksServiceId < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + cleanup_concurrent_column_rename :web_hooks, :service_id, :integration_id + end + + def down + undo_cleanup_concurrent_column_rename :web_hooks, :service_id, :integration_id + end +end diff --git a/db/schema_migrations/20220831090454 b/db/schema_migrations/20220831090454 new file mode 100644 index 00000000000..70f41257873 --- /dev/null +++ b/db/schema_migrations/20220831090454 @@ -0,0 +1 @@ +681514d675382385f77cbcb5ec22038555670f95a35f1ced42554452718bd193 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 715c6501eb3..f5d673f249e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -22,40 +22,6 @@ RETURN NULL; END $$; -CREATE FUNCTION function_for_trigger_a645cee67576() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - NEW."service_id" := NEW."integration_id"; - RETURN NEW; -END -$$; - -CREATE FUNCTION function_for_trigger_a87bcfdf0f0b() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - IF NEW."service_id" IS NULL AND NEW."integration_id" IS NOT NULL THEN - NEW."service_id" = NEW."integration_id"; - END IF; - - IF NEW."integration_id" IS NULL AND NEW."service_id" IS NOT NULL THEN - NEW."integration_id" = NEW."service_id"; - END IF; - - RETURN NEW; -END -$$; - -CREATE FUNCTION function_for_trigger_aca5c963d732() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - NEW."integration_id" := NEW."service_id"; - RETURN NEW; -END -$$; - CREATE FUNCTION gitlab_schema_prevent_write() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -22935,7 +22901,6 @@ CREATE TABLE web_hooks ( created_at timestamp without time zone, updated_at timestamp without time zone, type character varying DEFAULT 'ProjectHook'::character varying, - service_id integer, push_events boolean DEFAULT true NOT NULL, issues_events boolean DEFAULT false NOT NULL, merge_requests_events boolean DEFAULT false NOT NULL, @@ -30767,8 +30732,6 @@ CREATE INDEX index_web_hooks_on_project_id ON web_hooks USING btree (project_id) CREATE INDEX index_web_hooks_on_project_id_recent_failures ON web_hooks USING btree (project_id, recent_failures); -CREATE INDEX index_web_hooks_on_service_id ON web_hooks USING btree (service_id); - CREATE INDEX index_web_hooks_on_type ON web_hooks USING btree (type); CREATE UNIQUE INDEX index_webauthn_registrations_on_credential_xid ON webauthn_registrations USING btree (credential_xid); @@ -32241,12 +32204,6 @@ CREATE TRIGGER nullify_merge_request_metrics_build_data_on_update BEFORE UPDATE CREATE TRIGGER projects_loose_fk_trigger AFTER DELETE ON projects REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records(); -CREATE TRIGGER trigger_a645cee67576 BEFORE UPDATE OF integration_id ON web_hooks FOR EACH ROW EXECUTE FUNCTION function_for_trigger_a645cee67576(); - -CREATE TRIGGER trigger_a87bcfdf0f0b BEFORE INSERT ON web_hooks FOR EACH ROW EXECUTE FUNCTION function_for_trigger_a87bcfdf0f0b(); - -CREATE TRIGGER trigger_aca5c963d732 BEFORE UPDATE OF service_id ON web_hooks FOR EACH ROW EXECUTE FUNCTION function_for_trigger_aca5c963d732(); - CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace(); CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker(); @@ -33050,9 +33007,6 @@ ALTER TABLE ONLY environments ALTER TABLE ONLY ci_builds ADD CONSTRAINT fk_d3130c9a7f FOREIGN KEY (commit_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE; -ALTER TABLE ONLY web_hooks - ADD CONSTRAINT fk_d47999a98a FOREIGN KEY (service_id) REFERENCES integrations(id) ON DELETE CASCADE; - ALTER TABLE ONLY ci_sources_pipelines ADD CONSTRAINT fk_d4e29af7d7 FOREIGN KEY (source_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE; diff --git a/lib/gitlab/cache/ci/project_pipeline_status.rb b/lib/gitlab/cache/ci/project_pipeline_status.rb index 99ce1119c17..9209c9b4927 100644 --- a/lib/gitlab/cache/ci/project_pipeline_status.rb +++ b/lib/gitlab/cache/ci/project_pipeline_status.rb @@ -108,7 +108,7 @@ module Gitlab return self.loaded unless self.loaded.nil? Gitlab::Redis::Cache.with do |redis| - redis.exists(cache_key) + redis.exists?(cache_key) # rubocop:disable CodeReuse/ActiveRecord end end diff --git a/lib/gitlab/ci/trace.rb b/lib/gitlab/ci/trace.rb index c5664ef1cfb..2dc7bbc391e 100644 --- a/lib/gitlab/ci/trace.rb +++ b/lib/gitlab/ci/trace.rb @@ -140,7 +140,7 @@ module Gitlab def being_watched? Gitlab::Redis::SharedState.with do |redis| - redis.exists(being_watched_cache_key) + redis.exists?(being_watched_cache_key) # rubocop:disable CodeReuse/ActiveRecord end end diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb index 75d07a36dcd..0b18a337707 100644 --- a/lib/gitlab/exclusive_lease.rb +++ b/lib/gitlab/exclusive_lease.rb @@ -118,7 +118,7 @@ module Gitlab # Returns true if the key for this lease is set. def exists? Gitlab::Redis::SharedState.with do |redis| - redis.exists(@redis_shared_state_key) + redis.exists?(@redis_shared_state_key) # rubocop:disable CodeReuse/ActiveRecord end end diff --git a/lib/gitlab/repository_set_cache.rb b/lib/gitlab/repository_set_cache.rb index 33c7d96c45b..baf48fd0dc1 100644 --- a/lib/gitlab/repository_set_cache.rb +++ b/lib/gitlab/repository_set_cache.rb @@ -41,7 +41,7 @@ module Gitlab smembers, exists = with do |redis| redis.multi do |multi| multi.smembers(full_key) - multi.exists(full_key) + multi.exists?(full_key) # rubocop:disable CodeReuse/ActiveRecord end end @@ -58,7 +58,7 @@ module Gitlab full_key = cache_key(key) with do |redis| - exists = redis.exists(full_key) + exists = redis.exists?(full_key) # rubocop:disable CodeReuse/ActiveRecord write(key, yield) unless exists redis.sscan_each(full_key, match: pattern) diff --git a/lib/gitlab/set_cache.rb b/lib/gitlab/set_cache.rb index 23c23393bc8..c7818cb3418 100644 --- a/lib/gitlab/set_cache.rb +++ b/lib/gitlab/set_cache.rb @@ -28,7 +28,7 @@ module Gitlab end def exist?(key) - with { |redis| redis.exists(cache_key(key)) } + with { |redis| redis.exists?(cache_key(key)) } # rubocop:disable CodeReuse/ActiveRecord end def write(key, value) @@ -59,7 +59,7 @@ module Gitlab with do |redis| redis.multi do |multi| multi.sismember(full_key, value) - multi.exists(full_key) + multi.exists?(full_key) # rubocop:disable CodeReuse/ActiveRecord end end end diff --git a/lib/gitlab/sidekiq_daemon/monitor.rb b/lib/gitlab/sidekiq_daemon/monitor.rb index 1f1d63877b5..655e95c82d3 100644 --- a/lib/gitlab/sidekiq_daemon/monitor.rb +++ b/lib/gitlab/sidekiq_daemon/monitor.rb @@ -182,7 +182,7 @@ module Gitlab def cancelled?(jid) ::Gitlab::Redis::SharedState.with do |redis| - redis.exists(self.class.cancel_job_key(jid)) + redis.exists?(self.class.cancel_job_key(jid)) # rubocop:disable CodeReuse/ActiveRecord end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e7d77185cbd..d75242f9efc 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -35587,9 +35587,6 @@ msgstr "" msgid "SecurityOrchestration|%{scanners} %{severities} in an open merge request targeting %{branches}." msgstr "" -msgid "SecurityOrchestration|+%{count} more" -msgstr "" - msgid "SecurityOrchestration|, and %{count} more" msgstr "" diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb index aed310531e6..21810f64cb4 100644 --- a/spec/controllers/dashboard_controller_spec.rb +++ b/spec/controllers/dashboard_controller_spec.rb @@ -4,11 +4,14 @@ require 'spec_helper' RSpec.describe DashboardController do context 'signed in' do - let(:user) { create(:user) } - let(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + + before_all do + project.add_maintainer(user) + end before do - project.add_maintainer(user) sign_in(user) end @@ -30,6 +33,28 @@ RSpec.describe DashboardController do end it_behaves_like 'issuables requiring filter', :issues + + it 'includes tasks in issue list' do + task = create(:work_item, :task, project: project, author: user) + + get :issues, params: { author_id: user.id } + + expect(assigns[:issues].map(&:id)).to include(task.id) + end + + context 'when work_items is disabled' do + before do + stub_feature_flags(work_items: false) + end + + it 'does not include tasks in issue list' do + task = create(:work_item, :task, project: project, author: user) + + get :issues, params: { author_id: user.id } + + expect(assigns[:issues].map(&:id)).not_to include(task.id) + end + end end describe 'GET merge requests' do diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 64d4b276519..0c3795540e0 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -1701,13 +1701,27 @@ RSpec.describe Projects::IssuesController do end it 'allows CSV export' do - expect(IssuableExportCsvWorker).to receive(:perform_async).with(:issue, viewer.id, project.id, anything) + expect(IssuableExportCsvWorker).to receive(:perform_async) + .with(:issue, viewer.id, project.id, hash_including('issue_types' => Issue::TYPES_FOR_LIST)) request_csv expect(response).to redirect_to(project_issues_path(project)) expect(controller).to set_flash[:notice].to match(/\AYour CSV export has started/i) end + + context 'when work_items is disabled' do + before do + stub_feature_flags(work_items: false) + end + + it 'does not include tasks in CSV export' do + expect(IssuableExportCsvWorker).to receive(:perform_async) + .with(:issue, viewer.id, project.id, hash_including('issue_types' => Issue::TYPES_FOR_LIST.excluding('task'))) + + request_csv + end + end end context 'when not logged in' do diff --git a/spec/frontend/blob/3d_viewer/mesh_object_spec.js b/spec/frontend/blob/3d_viewer/mesh_object_spec.js index 3014af073f5..1b0fd362778 100644 --- a/spec/frontend/blob/3d_viewer/mesh_object_spec.js +++ b/spec/frontend/blob/3d_viewer/mesh_object_spec.js @@ -1,4 +1,4 @@ -import { BoxGeometry } from 'three/build/three.module'; +import { BoxGeometry } from 'three'; import MeshObject from '~/blob/3d_viewer/mesh_object'; describe('Mesh object', () => { diff --git a/spec/graphql/graphql_triggers_spec.rb b/spec/graphql/graphql_triggers_spec.rb index 5e2ab74a0e5..4d155a6c5f0 100644 --- a/spec/graphql/graphql_triggers_spec.rb +++ b/spec/graphql/graphql_triggers_spec.rb @@ -32,6 +32,20 @@ RSpec.describe GraphqlTriggers do end end + describe '.issuable_description_updated' do + it 'triggers the issuableDescriptionUpdated subscription' do + work_item = create(:work_item) + + expect(GitlabSchema.subscriptions).to receive(:trigger).with( + 'issuableDescriptionUpdated', + { issuable_id: work_item.to_gid }, + work_item + ).and_call_original + + GraphqlTriggers.issuable_description_updated(work_item) + end + end + describe '.issuable_labels_updated' do it 'triggers the issuableLabelsUpdated subscription' do project = create(:project) diff --git a/spec/graphql/types/subscription_type_spec.rb b/spec/graphql/types/subscription_type_spec.rb index 860cbbf0c15..0a92b51e7c6 100644 --- a/spec/graphql/types/subscription_type_spec.rb +++ b/spec/graphql/types/subscription_type_spec.rb @@ -8,6 +8,7 @@ RSpec.describe GitlabSchema.types['Subscription'] do issuable_assignees_updated issue_crm_contacts_updated issuable_title_updated + issuable_description_updated issuable_labels_updated issuable_dates_updated merge_request_reviewers_updated diff --git a/spec/initializers/0_log_deprecations_spec.rb b/spec/initializers/0_log_deprecations_spec.rb index d34be32f7d0..4bb4c9237c9 100644 --- a/spec/initializers/0_log_deprecations_spec.rb +++ b/spec/initializers/0_log_deprecations_spec.rb @@ -86,6 +86,18 @@ RSpec.describe '0_log_deprecations' do expect { warn('ABC gem is deprecated') }.to output.to_stderr end end + + it 'logs Redis exists_returns_integer deprecation message' do + msg = "`Redis#exists(key)` will return an Integer in redis-rb 4.3. `exists?` returns a boolean, you " \ + "should use it instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = " \ + "true. To disable this message and keep the current (boolean) behaviour of 'exists' you can set " \ + "`Redis.exists_returns_integer = false`, but this option will be removed in 5.0.0. " \ + "(#{::Kernel.caller(1, 1).first})\n" + + expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(message: msg.strip, source: 'redis') + + expect { warn(msg) }.to output.to_stderr + end end describe 'Rails deprecations' do diff --git a/spec/lib/gitlab/anonymous_session_spec.rb b/spec/lib/gitlab/anonymous_session_spec.rb index 64186e9003a..08087096d49 100644 --- a/spec/lib/gitlab/anonymous_session_spec.rb +++ b/spec/lib/gitlab/anonymous_session_spec.rb @@ -61,7 +61,7 @@ RSpec.describe Gitlab::AnonymousSession, :clean_gitlab_redis_sessions do subject.cleanup_session_per_ip_count Gitlab::Redis::Sessions.with do |redis| - expect(redis.exists("session:lookup:ip:gitlab2:127.0.0.1")).to eq(false) + expect(redis.exists?("session:lookup:ip:gitlab2:127.0.0.1")).to eq(false) end end end diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb index c0e4d1b5355..c78140a70b3 100644 --- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb +++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb @@ -288,7 +288,7 @@ RSpec.describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cac it 'deletes values from redis_cache' do pipeline_status.delete_from_cache - key_exists = Gitlab::Redis::Cache.with { |redis| redis.exists(cache_key) } + key_exists = Gitlab::Redis::Cache.with { |redis| redis.exists?(cache_key) } expect(key_exists).to be_falsy end diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb index 3043c8c5467..321a47c0634 100644 --- a/spec/lib/gitlab/ci/trace_spec.rb +++ b/spec/lib/gitlab/ci/trace_spec.rb @@ -74,7 +74,7 @@ RSpec.describe Gitlab::Ci::Trace, :clean_gitlab_redis_shared_state, factory_defa trace.being_watched! result = Gitlab::Redis::SharedState.with do |redis| - redis.exists(cache_key) + redis.exists?(cache_key) end expect(result).to eq(true) diff --git a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb index 52b33e22089..936c63fd6cd 100644 --- a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ context 'hook object' do let(:relation_sym) { :hooks } let(:id) { 999 } - let(:service_id) { 99 } + let(:integration_id) { 99 } let(:original_project_id) { 8 } let(:token) { 'secret' } @@ -52,7 +52,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ 'project_id' => original_project_id, 'created_at' => '2016-08-12T09:41:03.462Z', 'updated_at' => '2016-08-12T09:41:03.462Z', - 'service_id' => service_id, + 'integration_id' => integration_id, 'push_events' => true, 'issues_events' => false, 'confidential_issues_events' => false, @@ -71,8 +71,8 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ expect(created_object.id).not_to eq(id) end - it 'does not have the original service_id' do - expect(created_object.service_id).not_to eq(service_id) + it 'does not have the original integration_id' do + expect(created_object.integration_id).not_to eq(integration_id) end it 'does not have the original project_id' do @@ -88,10 +88,10 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ end context 'original service exists' do - let(:service_id) { create(:integration, project: project).id } + let(:integration_id) { create(:integration, project: project).id } - it 'does not have the original service_id' do - expect(created_object.service_id).not_to eq(service_id) + it 'does not have the original integration_id' do + expect(created_object.integration_id).not_to eq(integration_id) end end @@ -302,7 +302,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ let(:relation_sym) { :hazardous_foo_model } let(:relation_hash) do { - 'service_id' => 99, + 'integration_id' => 99, 'moved_to_id' => 99, 'namespace_id' => 99, 'ci_id' => 99, @@ -317,7 +317,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_ before do stub_const('HazardousFooModel', Class.new(FooModel)) HazardousFooModel.class_eval do - attr_accessor :service_id, :moved_to_id, :namespace_id, :ci_id, :random_project_id, :random_id, :milestone_id, :project_id + attr_accessor :integration_id, :moved_to_id, :namespace_id, :ci_id, :random_project_id, :random_id, :milestone_id, :project_id end allow(HazardousFooModel).to receive(:reflect_on_association).and_return(nil) diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb index 027697db7e1..7f1504a8df9 100644 --- a/spec/lib/gitlab/sidekiq_status_spec.rb +++ b/spec/lib/gitlab/sidekiq_status_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_ key = described_class.key_for('123') with_redis do |redis| - expect(redis.exists(key)).to eq(true) + expect(redis.exists?(key)).to eq(true) expect(redis.ttl(key) > 0).to eq(true) expect(redis.get(key)).to eq('1') end @@ -23,7 +23,7 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_ key = described_class.key_for('123') with_redis do |redis| - expect(redis.exists(key)).to eq(true) + expect(redis.exists?(key)).to eq(true) expect(redis.ttl(key) > described_class::DEFAULT_EXPIRATION).to eq(true) expect(redis.get(key)).to eq('1') end @@ -35,7 +35,7 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_ key = described_class.key_for('123') with_redis do |redis| - expect(redis.exists(key)).to eq(false) + expect(redis.exists?(key)).to eq(false) end end end @@ -48,7 +48,7 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_ key = described_class.key_for('123') with_redis do |redis| - expect(redis.exists(key)).to eq(false) + expect(redis.exists?(key)).to eq(false) end end end diff --git a/spec/models/ci/build_trace_chunks/redis_spec.rb b/spec/models/ci/build_trace_chunks/redis_spec.rb index c004887d609..0d8cda7b3d8 100644 --- a/spec/models/ci/build_trace_chunks/redis_spec.rb +++ b/spec/models/ci/build_trace_chunks/redis_spec.rb @@ -211,15 +211,15 @@ RSpec.describe Ci::BuildTraceChunks::Redis, :clean_gitlab_redis_shared_state do it 'deletes multiple data' do Gitlab::Redis::SharedState.with do |redis| - expect(redis.exists("gitlab:ci:trace:#{build.id}:chunks:0")).to be_truthy - expect(redis.exists("gitlab:ci:trace:#{build.id}:chunks:1")).to be_truthy + expect(redis.exists?("gitlab:ci:trace:#{build.id}:chunks:0")).to eq(true) + expect(redis.exists?("gitlab:ci:trace:#{build.id}:chunks:1")).to eq(true) end subject Gitlab::Redis::SharedState.with do |redis| - expect(redis.exists("gitlab:ci:trace:#{build.id}:chunks:0")).to be_falsy - expect(redis.exists("gitlab:ci:trace:#{build.id}:chunks:1")).to be_falsy + expect(redis.exists?("gitlab:ci:trace:#{build.id}:chunks:0")).to eq(false) + expect(redis.exists?("gitlab:ci:trace:#{build.id}:chunks:1")).to eq(false) end end end diff --git a/spec/models/concerns/counter_attribute_spec.rb b/spec/models/concerns/counter_attribute_spec.rb index 2dd70188740..66ccd4559e5 100644 --- a/spec/models/concerns/counter_attribute_spec.rb +++ b/spec/models/concerns/counter_attribute_spec.rb @@ -73,8 +73,8 @@ RSpec.describe CounterAttribute, :counter_attribute, :clean_gitlab_redis_shared_ subject Gitlab::Redis::SharedState.with do |redis| - expect(redis.exists(increment_key)).to be_falsey - expect(redis.exists(flushed_key)).to eq(flushed_key_present) + expect(redis.exists?(increment_key)).to eq(false) + expect(redis.exists?(flushed_key)).to eq(flushed_key_present) end end end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 8a2e9ed74f7..2cc3d50f290 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -495,6 +495,32 @@ RSpec.describe Issues::UpdateService, :mailer do expect(note.note).to eq('changed the description') end + + it 'triggers GraphQL description updated subscription' do + expect(GraphqlTriggers).to receive(:issuable_description_updated).with(issue).and_call_original + + update_issue(description: 'Changed description') + end + + context 'when broadcast_issuable_description_updated is disabled' do + before do + stub_feature_flags(broadcast_issuable_description_updated: false) + end + + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_issue(title: 'Changed title') + end + end + end + + context 'when decription is not changed' do + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_issue(title: 'Changed title') + end end context 'when issue turns confidential' do diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 8ebabd64d8a..5d76fb051f2 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -625,6 +625,32 @@ RSpec.describe MergeRequests::UpdateService, :mailer do expect(Todo.count).to eq(2) end + + it 'triggers GraphQL description updated subscription' do + expect(GraphqlTriggers).to receive(:issuable_description_updated).with(merge_request).and_call_original + + update_merge_request(description: 'updated description') + end + + context 'when broadcast_issuable_description_updated is disabled' do + before do + stub_feature_flags(broadcast_issuable_description_updated: false) + end + + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_merge_request(description: 'updated description') + end + end + end + + context 'when decription is not changed' do + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_merge_request(title: 'updated title') + end end context 'when is reassigned' do diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb index e8b82b0b4f2..ae5785a8c4b 100644 --- a/spec/services/work_items/update_service_spec.rb +++ b/spec/services/work_items/update_service_spec.rb @@ -88,6 +88,38 @@ RSpec.describe WorkItems::UpdateService do end end + context 'when decription is changed' do + let(:opts) { { description: 'description changed' } } + + it 'triggers GraphQL description updated subscription' do + expect(GraphqlTriggers).to receive(:issuable_description_updated).with(work_item).and_call_original + + update_work_item + end + + context 'when broadcast_issuable_description_updated is disabled' do + before do + stub_feature_flags(broadcast_issuable_description_updated: false) + end + + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_work_item + end + end + end + + context 'when decription is not changed' do + let(:opts) { { title: 'title changed' } } + + it 'does not trigger GraphQL description updated subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_description_updated) + + update_work_item + end + end + context 'when updating state_event' do context 'when state_event is close' do let(:opts) { { state_event: 'close' } } diff --git a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb index f3a12578912..91e517270ff 100644 --- a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb @@ -124,14 +124,14 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| it 'removes the increment entry from Redis' do Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists(model.counter_key(incremented_attribute)) + key_exists = redis.exists?(model.counter_key(incremented_attribute)) expect(key_exists).to be_truthy end subject Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists(model.counter_key(incremented_attribute)) + key_exists = redis.exists?(model.counter_key(incremented_attribute)) expect(key_exists).to be_falsey end end @@ -162,7 +162,7 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| subject Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists(model.counter_flushed_key(incremented_attribute)) + key_exists = redis.exists?(model.counter_flushed_key(incremented_attribute)) expect(key_exists).to be_falsey end end @@ -208,7 +208,7 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| model.clear_counter!(attribute) Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists(model.counter_key(attribute)) + key_exists = redis.exists?(model.counter_key(attribute)) expect(key_exists).to be_falsey end end diff --git a/spec/support/shared_examples/models/integrations/has_web_hook_shared_examples.rb b/spec/support/shared_examples/models/integrations/has_web_hook_shared_examples.rb index 2f693edeb53..a341497a456 100644 --- a/spec/support/shared_examples/models/integrations/has_web_hook_shared_examples.rb +++ b/spec/support/shared_examples/models/integrations/has_web_hook_shared_examples.rb @@ -4,7 +4,7 @@ RSpec.shared_examples Integrations::HasWebHook do include AfterNextHelpers describe 'associations' do - it { is_expected.to have_one(:service_hook).inverse_of(:integration).with_foreign_key(:service_id) } + it { is_expected.to have_one(:service_hook).inverse_of(:integration).with_foreign_key(:integration_id) } end describe 'callbacks' do