From 0328f921b0653aaf1c20ffe55a66ad6657f24003 Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 22 Nov 2021 09:38:36 +0800 Subject: [PATCH 1/9] Refactor to add BaseThirdPartyWiki Only one third-party wiki service can be active at a time. Changelog: changed --- app/models/integration.rb | 1 + .../integrations/base_third_party_wiki.rb | 37 +++++++++++++++++++ app/models/integrations/confluence.rb | 15 +------- app/models/integrations/shimo.rb | 17 +-------- locale/gitlab.pot | 3 ++ .../base_third_party_wiki_spec.rb | 34 +++++++++++++++++ 6 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 app/models/integrations/base_third_party_wiki.rb create mode 100644 spec/models/integrations/base_third_party_wiki_spec.rb diff --git a/app/models/integration.rb b/app/models/integration.rb index 29d96650a813be..d40d90a2efb8c7 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -74,6 +74,7 @@ class Integration < ApplicationRecord validate :validate_belongs_to_project_or_group scope :external_issue_trackers, -> { where(category: 'issue_tracker').active } + scope :third_party_wikis, -> { where(category: 'third_party_wiki').active } scope :external_wikis, -> { where(type: 'ExternalWikiService').active } scope :active, -> { where(active: true) } scope :by_type, -> (type) { where(type: type) } diff --git a/app/models/integrations/base_third_party_wiki.rb b/app/models/integrations/base_third_party_wiki.rb new file mode 100644 index 00000000000000..6a9cfa33157423 --- /dev/null +++ b/app/models/integrations/base_third_party_wiki.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Integrations + class BaseThirdPartyWiki < Integration + default_value_for :category, 'third_party_wiki' + + validate :only_one_third_party_wiki, if: :activated?, on: :manual_change + + after_commit :cache_project_has_integration + + def self.supported_events + %w() + end + + private + + def only_one_third_party_wiki + return if template? || instance? + return if project.blank? + + if project.integrations.third_party_wikis.where.not(id: id).any? + errors.add(:base, _('Another third-party wiki is already in use. Only one third-party wiki service can be active at a time')) + end + end + + def cache_project_has_integration + return unless project && !project.destroyed? + + project.project_setting.save! unless project.project_setting.persisted? + project.project_setting.update_column(project_settings_cache_key, active?) + end + + def project_settings_cache_key + "has_#{self.class.name.demodulize.underscore}" + end + end +end diff --git a/app/models/integrations/confluence.rb b/app/models/integrations/confluence.rb index 7f111f482dddba..d843878565ea06 100644 --- a/app/models/integrations/confluence.rb +++ b/app/models/integrations/confluence.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Integrations - class Confluence < Integration + class Confluence < BaseThirdPartyWiki include ActionView::Helpers::UrlHelper VALID_SCHEME_MATCH = %r{\Ahttps?\Z}.freeze @@ -13,16 +13,10 @@ class Confluence < Integration validates :confluence_url, presence: true, if: :activated? validate :validate_confluence_url_is_cloud, if: :activated? - after_commit :cache_project_has_confluence - def self.to_param 'confluence' end - def self.supported_events - %w() - end - def title s_('ConfluenceService|Confluence Workspace') end @@ -82,12 +76,5 @@ def confluence_uri_valid? rescue URI::InvalidURIError false end - - def cache_project_has_confluence - return unless project && !project.destroyed? - - project.project_setting.save! unless project.project_setting.persisted? - project.project_setting.update_column(:has_confluence, active?) - end end end diff --git a/app/models/integrations/shimo.rb b/app/models/integrations/shimo.rb index 0e1023bb7a7b80..dd25a0bc558ac5 100644 --- a/app/models/integrations/shimo.rb +++ b/app/models/integrations/shimo.rb @@ -1,12 +1,10 @@ # frozen_string_literal: true module Integrations - class Shimo < Integration + class Shimo < BaseThirdPartyWiki prop_accessor :external_wiki_url validates :external_wiki_url, presence: true, public_url: true, if: :activated? - after_commit :cache_project_has_shimo - def render? return false unless Feature.enabled?(:shimo_integration, project) @@ -33,10 +31,6 @@ def execute(_data) nil end - def self.supported_events - %w() - end - def fields [ { @@ -47,14 +41,5 @@ def fields } ] end - - private - - def cache_project_has_shimo - return unless project && !project.destroyed? - - project.project_setting.save! unless project.project_setting.persisted? - project.project_setting.update_column(:has_shimo, activated?) - end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 74049e27dacb17..7326acd9c91b24 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4003,6 +4003,9 @@ msgstr "" msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time" msgstr "" +msgid "Another third-party wiki is already in use. Only one third-party wiki service can be active at a time" +msgstr "" + msgid "Anti-spam verification" msgstr "" diff --git a/spec/models/integrations/base_third_party_wiki_spec.rb b/spec/models/integrations/base_third_party_wiki_spec.rb new file mode 100644 index 00000000000000..d275e072bd92b1 --- /dev/null +++ b/spec/models/integrations/base_third_party_wiki_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Integrations::BaseThirdPartyWiki do + describe 'Validations' do + let_it_be_with_reload(:project) { create :project } + + describe 'only one third party wiki per project' do + subject(:integration) { create(:shimo_integration, project: project, active: true) } + + before do + create(:confluence_integration, project: project, active: true) + end + + context 'when integration is changed manually by user' do + it 'executes the validation' do + valid = integration.valid?(:manual_change) + + expect(valid).to be_falsey + expect(integration.errors[:base]).to include( + _('Another third-party wiki is already in use. Only one third-party wiki service can be active at a time') + ) + end + end + + context 'when integration is changed internally' do + it 'does not execute the validation' do + expect(integration.valid?).to be_truthy + end + end + end + end +end -- GitLab From f92d660c3f04eb0aa2f5950cf657c4245dccf003 Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 15:08:30 +0800 Subject: [PATCH 2/9] Fix create code style in spec --- spec/models/integrations/base_third_party_wiki_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/integrations/base_third_party_wiki_spec.rb b/spec/models/integrations/base_third_party_wiki_spec.rb index d275e072bd92b1..1511185df50a02 100644 --- a/spec/models/integrations/base_third_party_wiki_spec.rb +++ b/spec/models/integrations/base_third_party_wiki_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Integrations::BaseThirdPartyWiki do describe 'Validations' do - let_it_be_with_reload(:project) { create :project } + let_it_be_with_reload(:project) { create(:project) } describe 'only one third party wiki per project' do subject(:integration) { create(:shimo_integration, project: project, active: true) } -- GitLab From 4c60bad3671aa728935349ad02ea58d54b3210da Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 15:43:31 +0800 Subject: [PATCH 3/9] Create 20211129073034_update_shimo_service_category.rb --- .../20211129073034_update_shimo_service_category.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 db/post_migrate/20211129073034_update_shimo_service_category.rb diff --git a/db/post_migrate/20211129073034_update_shimo_service_category.rb b/db/post_migrate/20211129073034_update_shimo_service_category.rb new file mode 100644 index 00000000000000..cc241c5b841f6d --- /dev/null +++ b/db/post_migrate/20211129073034_update_shimo_service_category.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class UpdateShimoServiceCategory < Gitlab::Database::Migration[1.0] + disable_ddl_transaction! + def up + Integrations::Shimo.update_all(category: 'third_party_wiki') + end + + def down + Integrations::Shimo.update_all(category: 'common') + end +end -- GitLab From 11ca8bbf66d77bea8fec74679ad3221eddc4c2dd Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 15:43:37 +0800 Subject: [PATCH 4/9] Create 20211129073035_update_confluence_service_category.rb --- ...11129073035_update_confluence_service_category.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 db/post_migrate/20211129073035_update_confluence_service_category.rb diff --git a/db/post_migrate/20211129073035_update_confluence_service_category.rb b/db/post_migrate/20211129073035_update_confluence_service_category.rb new file mode 100644 index 00000000000000..3d8420732bd018 --- /dev/null +++ b/db/post_migrate/20211129073035_update_confluence_service_category.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class UpdateConfluenceServiceCategory < Gitlab::Database::Migration[1.0] + disable_ddl_transaction! + def up + Integrations::Confluence.update_all(category: 'third_party_wiki') + end + + def down + Integrations::Confluence.update_all(category: 'common') + end +end -- GitLab From 8514ef241a504689057b2bca421592bd30533668 Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 15:44:16 +0800 Subject: [PATCH 5/9] Add db/schema_migrations timestamp --- db/schema_migrations/20211129073034 | 1 + db/schema_migrations/20211129073035 | 1 + 2 files changed, 2 insertions(+) create mode 100644 db/schema_migrations/20211129073034 create mode 100644 db/schema_migrations/20211129073035 diff --git a/db/schema_migrations/20211129073034 b/db/schema_migrations/20211129073034 new file mode 100644 index 00000000000000..38f9e68191ca18 --- /dev/null +++ b/db/schema_migrations/20211129073034 @@ -0,0 +1 @@ +8d1cdf689dc422a435978d359680c2d2a684f73ad588c5c4388f01782fba17d1 \ No newline at end of file diff --git a/db/schema_migrations/20211129073035 b/db/schema_migrations/20211129073035 new file mode 100644 index 00000000000000..1535a69f0dd7c4 --- /dev/null +++ b/db/schema_migrations/20211129073035 @@ -0,0 +1 @@ +4863f144eedf72c9b42e49f3b9a3dd07f01e783afade9538187658a7f632d58f \ No newline at end of file -- GitLab From d36e06c71a67e2310d532e89ab4b51a13d697db2 Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 15:52:38 +0800 Subject: [PATCH 6/9] Update third_party_wikis --- app/models/integration.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/integration.rb b/app/models/integration.rb index d40d90a2efb8c7..8007c41683f2ae 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -74,7 +74,10 @@ class Integration < ApplicationRecord validate :validate_belongs_to_project_or_group scope :external_issue_trackers, -> { where(category: 'issue_tracker').active } - scope :third_party_wikis, -> { where(category: 'third_party_wiki').active } + scope :third_party_wikis, -> { where(type: %w[ConfluenceService ShimoService]).active } + # TODO: Will be modified in 14.7 + # Details: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74501#note_744393645 + # scope :third_party_wikis, -> { where(category: 'third_party_wiki').active } scope :external_wikis, -> { where(type: 'ExternalWikiService').active } scope :active, -> { where(active: true) } scope :by_type, -> (type) { where(type: type) } -- GitLab From 69842d0fc0c76969fad4338eeac53f4a8970edac Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 16:02:12 +0800 Subject: [PATCH 7/9] Update only_one_third_party_wiki --- app/models/integrations/base_third_party_wiki.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/integrations/base_third_party_wiki.rb b/app/models/integrations/base_third_party_wiki.rb index 6a9cfa33157423..67d516c6b58005 100644 --- a/app/models/integrations/base_third_party_wiki.rb +++ b/app/models/integrations/base_third_party_wiki.rb @@ -15,8 +15,7 @@ def self.supported_events private def only_one_third_party_wiki - return if template? || instance? - return if project.blank? + return unless project_level? if project.integrations.third_party_wikis.where.not(id: id).any? errors.add(:base, _('Another third-party wiki is already in use. Only one third-party wiki service can be active at a time')) -- GitLab From e3aa107969f093b6a4fd048c1a345f080e38470d Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 16:08:58 +0800 Subject: [PATCH 8/9] Update third_party_wiki_menu --- lib/sidebars/projects/panel.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb index 6bb4fb52e2ad69..13428ec1d4abfc 100644 --- a/lib/sidebars/projects/panel.rb +++ b/lib/sidebars/projects/panel.rb @@ -54,7 +54,9 @@ def third_party_wiki_menu wiki_menu_list = [::Sidebars::Projects::Menus::ConfluenceMenu] wiki_menu_list << ::Sidebars::Projects::Menus::ShimoMenu if Feature.enabled?(:shimo_integration, context.project) - wiki_menu_list.find { |wiki_menu| wiki_menu.new(context).render? } + wiki_menu_list.filter do |wiki_menu| + wiki_menu.new(context).render? + end.presence end end end -- GitLab From afb60c26678b017f629200f99d8497b73dd02603 Mon Sep 17 00:00:00 2001 From: Baodong Date: Mon, 29 Nov 2021 17:27:19 +0800 Subject: [PATCH 9/9] Fix third_party_wiki_menus --- lib/sidebars/projects/panel.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb index 13428ec1d4abfc..ee982d4eff26dd 100644 --- a/lib/sidebars/projects/panel.rb +++ b/lib/sidebars/projects/panel.rb @@ -46,17 +46,17 @@ def add_invite_members_menu end def add_wiki_menus - add_menu((third_party_wiki_menu || Sidebars::Projects::Menus::WikiMenu).new(context)) + third_party_wiki_menus.each { |menu| add_menu(menu.new(context)) } add_menu(Sidebars::Projects::Menus::ExternalWikiMenu.new(context)) end - def third_party_wiki_menu + def third_party_wiki_menus wiki_menu_list = [::Sidebars::Projects::Menus::ConfluenceMenu] wiki_menu_list << ::Sidebars::Projects::Menus::ShimoMenu if Feature.enabled?(:shimo_integration, context.project) wiki_menu_list.filter do |wiki_menu| wiki_menu.new(context).render? - end.presence + end.presence || [Sidebars::Projects::Menus::WikiMenu] end end end -- GitLab