mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Use registry for associated journal objects, not hard coded map
This commit is contained in:
@@ -32,19 +32,20 @@ class Journals::CreateService
|
||||
class Association
|
||||
include Helpers
|
||||
|
||||
ASSOCIATION_NAMES = %i[
|
||||
AgendaItemable
|
||||
Attachable
|
||||
CustomComment
|
||||
Customizable
|
||||
ProjectPhase
|
||||
Storable
|
||||
].freeze
|
||||
# Core associations are defined here. Module-specific associations can be defined in engines
|
||||
# using `Journals::CreateService::Association.register`.
|
||||
@registry = Set.new(%i[Attachable CustomComment Customizable ProjectPhase])
|
||||
|
||||
def self.for(journable)
|
||||
ASSOCIATION_NAMES
|
||||
.map { "Journals::CreateService::#{it}".constantize.new(journable) }
|
||||
.select(&:associated?)
|
||||
class << self
|
||||
def register(*names)
|
||||
@registry.merge(names.map(&:to_sym))
|
||||
end
|
||||
|
||||
def for(journable)
|
||||
@registry
|
||||
.map { "Journals::CreateService::#{it}".constantize.new(journable) }
|
||||
.select(&:associated?)
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :journable
|
||||
|
||||
@@ -195,6 +195,8 @@ module OpenProject::Meeting
|
||||
::Exports::Register.register do
|
||||
single(::Meeting, Meetings::Exporter)
|
||||
end
|
||||
|
||||
Journals::CreateService::Association.register(:AgendaItemable)
|
||||
end
|
||||
|
||||
add_api_path :meetings do
|
||||
|
||||
@@ -256,6 +256,8 @@ module OpenProject::Storages
|
||||
|
||||
# This hook is executed when the module is loaded.
|
||||
config.to_prepare do
|
||||
Journals::CreateService::Association.register(:Storable)
|
||||
|
||||
# Load Storages::Storage descendants due to STI
|
||||
Storages::Storage::InexistentStorage
|
||||
Storages::OneDriveStorage
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Journals::CreateService::Association do
|
||||
describe ".register" do
|
||||
around do |example|
|
||||
original = described_class.instance_variable_get(:@registry).dup
|
||||
example.run
|
||||
ensure
|
||||
described_class.instance_variable_set(:@registry, original)
|
||||
end
|
||||
|
||||
it "adds a new name to the registry" do
|
||||
expect { described_class.register(:NewAssociation) }
|
||||
.to change { described_class.instance_variable_get(:@registry) }
|
||||
.to include(:NewAssociation)
|
||||
end
|
||||
|
||||
it "is idempotent — duplicate registrations are ignored" do
|
||||
described_class.register(:NewAssociation)
|
||||
expect { described_class.register(:NewAssociation) }
|
||||
.not_to change { described_class.instance_variable_get(:@registry).size }
|
||||
end
|
||||
|
||||
it "accepts strings and coerces them to symbols" do
|
||||
described_class.register("NewAssociation")
|
||||
expect(described_class.instance_variable_get(:@registry)).to include(:NewAssociation)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".for" do
|
||||
it "includes core associations for any journable" do
|
||||
journable = instance_double(WorkPackage, customizable?: true, respond_to?: false)
|
||||
allow(journable).to receive(:respond_to?).with(:attachable?).and_return(true)
|
||||
allow(journable).to receive(:respond_to?).with(:custom_comments).and_return(false)
|
||||
allow(journable).to receive(:respond_to?).with(:file_links).and_return(false)
|
||||
allow(journable).to receive(:respond_to?).with(:agenda_items).and_return(false)
|
||||
allow(journable).to receive(:respond_to?).with(:phases).and_return(false)
|
||||
|
||||
associations = described_class.for(journable)
|
||||
expect(associations.map(&:class)).to include(Journals::CreateService::Attachable)
|
||||
end
|
||||
|
||||
it "excludes associations whose #associated? returns false" do
|
||||
journable = instance_double(WorkPackage, customizable?: false, respond_to?: false)
|
||||
allow(journable).to receive(:respond_to?).and_return(false)
|
||||
|
||||
associations = described_class.for(journable)
|
||||
expect(associations).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user